@sunbird-cb/toc 0.0.7 → 0.0.9

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 (331) hide show
  1. package/esm2022/lib/_collection/_common/attendance-card/attendance-card.component.mjs +55 -55
  2. package/esm2022/lib/_collection/_common/attendance-card/attendance-card.module.mjs +126 -126
  3. package/esm2022/lib/_collection/_common/attendance-helper/attendance-helper.component.mjs +32 -32
  4. package/esm2022/lib/_collection/_common/attendance-helper/attendance-helper.module.mjs +85 -85
  5. package/esm2022/lib/_collection/_common/avatar-photo/avatar-photo.component.mjs +100 -100
  6. package/esm2022/lib/_collection/_common/avatar-photo/avatar-photo.module.mjs +48 -48
  7. package/esm2022/lib/_collection/_common/certificate-dialog/certificate-dialog.component.mjs +120 -120
  8. package/esm2022/lib/_collection/_common/certificate-dialog/certificate-dialog.module.mjs +92 -92
  9. package/esm2022/lib/_collection/_common/certificate-dialog/svg-to-pdf.component.mjs +48 -48
  10. package/esm2022/lib/_collection/_common/confirm-dialog/confirm-dialog.component.mjs +25 -25
  11. package/esm2022/lib/_collection/_common/confirm-dialog/confirm-dialog.module.mjs +41 -41
  12. package/esm2022/lib/_collection/_common/connection-hover-card/connection-hover-card.component.mjs +89 -89
  13. package/esm2022/lib/_collection/_common/connection-hover-card/connection-hover.module.mjs +42 -42
  14. package/esm2022/lib/_collection/_common/connection-hover-card/connection-hover.servive.mjs +41 -41
  15. package/esm2022/lib/_collection/_common/connection-name/connection-name.component.mjs +78 -78
  16. package/esm2022/lib/_collection/_common/connection-name/connection-name.module.mjs +45 -45
  17. package/esm2022/lib/_collection/_common/connection-name/profile-v2.model.mjs +2 -2
  18. package/esm2022/lib/_collection/_common/content-progress/content-progress.component.mjs +70 -70
  19. package/esm2022/lib/_collection/_common/content-progress/content-progress.module.mjs +28 -28
  20. package/esm2022/lib/_collection/_common/content-rating-v2-dialog/content-rating-v2-dialog.component.mjs +187 -187
  21. package/esm2022/lib/_collection/_common/content-rating-v2-dialog/content-rating-v2-dialog.module.mjs +86 -86
  22. package/esm2022/lib/_collection/_common/content-toc/ai-tutor-confirm-popup/ai-tutor-confirm-popup.component.mjs +31 -31
  23. package/esm2022/lib/_collection/_common/content-toc/app-toc-about/app-toc-about.component.mjs +941 -941
  24. package/esm2022/lib/_collection/_common/content-toc/app-toc-assignment-viewer/app-toc-assignment-viewer.component.mjs +183 -183
  25. package/esm2022/lib/_collection/_common/content-toc/app-toc-assignment-viewerV2/app-toc-assignment-viewerV2.component.mjs +327 -327
  26. package/esm2022/lib/_collection/_common/content-toc/app-toc-batch-assignments/app-toc-batch-assignments.component.mjs +297 -297
  27. package/esm2022/lib/_collection/_common/content-toc/app-toc-content/app-toc-content.component.mjs +248 -225
  28. package/esm2022/lib/_collection/_common/content-toc/app-toc-content-card-v2/app-toc-content-card-v2.component.mjs +1148 -1030
  29. package/esm2022/lib/_collection/_common/content-toc/app-toc-content-card-v2-skeleton/app-toc-content-card-v2-skeleton.component.mjs +16 -16
  30. package/esm2022/lib/_collection/_common/content-toc/app-toc-reference-notes/app-toc-reference-notes.component.mjs +43 -43
  31. package/esm2022/lib/_collection/_common/content-toc/app-toc-session-card-new/app-toc-session-card-new.component.mjs +133 -133
  32. package/esm2022/lib/_collection/_common/content-toc/app-toc-sessions-new/app-toc-sessions-new.component.mjs +66 -66
  33. package/esm2022/lib/_collection/_common/content-toc/app-toc-teachers-notes/app-toc-teachers-notes.component.mjs +278 -278
  34. package/esm2022/lib/_collection/_common/content-toc/content-services/handle-claim.service.mjs +21 -21
  35. package/esm2022/lib/_collection/_common/content-toc/content-services/review-component-data.service.mjs +21 -21
  36. package/esm2022/lib/_collection/_common/content-toc/content-toc.component.mjs +847 -847
  37. package/esm2022/lib/_collection/_common/content-toc/content-toc.module.mjs +219 -219
  38. package/esm2022/lib/_collection/_common/content-toc/karma-points/karma-points.component.mjs +209 -209
  39. package/esm2022/lib/_collection/_common/content-toc/karma-points/karma-points.module.mjs +26 -26
  40. package/esm2022/lib/_collection/_common/content-toc/pipes/replace-nbsp.pipe.mjs +19 -19
  41. package/esm2022/lib/_collection/_common/content-toc/pipes/truncate.pipe.mjs +23 -23
  42. package/esm2022/lib/_collection/_common/content-toc/reviews-content/reviews-content.component.mjs +113 -113
  43. package/esm2022/lib/_collection/_common/content-toc/samuhik-charcha-content/samuhik-charcha-content/samuhik-charcha-content.component.mjs +110 -110
  44. package/esm2022/lib/_collection/_common/display-content-type/display-content-type.component.mjs +26 -26
  45. package/esm2022/lib/_collection/_common/display-content-type/display-content-type.module.mjs +19 -19
  46. package/esm2022/lib/_collection/_common/display-content-type-icon/display-content-type-icon.component.mjs +67 -67
  47. package/esm2022/lib/_collection/_common/display-content-type-icon/display-content-type-icon.module.mjs +28 -28
  48. package/esm2022/lib/_collection/_common/mark-as-complete/mark-as-complete.component.mjs +77 -77
  49. package/esm2022/lib/_collection/_common/mark-as-complete/mark-as-complete.model.mjs +2 -2
  50. package/esm2022/lib/_collection/_common/mark-as-complete/mark-as-complete.module.mjs +61 -61
  51. package/esm2022/lib/_collection/_common/pipe-content-route/pipe-content-route.module.mjs +20 -20
  52. package/esm2022/lib/_collection/_common/pipe-content-route/pipe-content-route.pipe.mjs +67 -67
  53. package/esm2022/lib/_collection/_common/player-brief/player-brief.component.mjs +139 -139
  54. package/esm2022/lib/_collection/_common/player-brief/player-brief.module.mjs +71 -71
  55. package/esm2022/lib/_collection/_common/rating-summary/rating-summary.component.mjs +34 -34
  56. package/esm2022/lib/_collection/_common/rating-summary/rating-summary.module.mjs +56 -56
  57. package/esm2022/lib/_collection/_common/skeleton-loader/skeleton-loader.component.mjs +25 -25
  58. package/esm2022/lib/_collection/_common/skeleton-loader/skeleton-loader.module.mjs +37 -37
  59. package/esm2022/lib/_collection/_common/tips-for-learner/tips-for-learner-card/tips-for-learner-card.component.mjs +32 -32
  60. package/esm2022/lib/_collection/_common/tips-for-learner/tips-for-learner.module.mjs +30 -30
  61. package/esm2022/lib/_collection/_common/toc-kpi-values/toc-kpi-values.component.mjs +38 -38
  62. package/esm2022/lib/_collection/_common/toc-kpi-values/toc-kpi-values.module.mjs +51 -51
  63. package/esm2022/lib/_collection/_common/user-autocomplete/user-autocomplete.component.mjs +115 -115
  64. package/esm2022/lib/_collection/_common/user-autocomplete/user-autocomplete.model.mjs +12 -12
  65. package/esm2022/lib/_collection/_common/user-autocomplete/user-autocomplete.module.mjs +51 -51
  66. package/esm2022/lib/_collection/_common/user-autocomplete/user-autocomplete.service.mjs +61 -61
  67. package/esm2022/lib/_collection/_common/user-content-rating/user-content-rating.component.mjs +87 -87
  68. package/esm2022/lib/_collection/_common/user-content-rating/user-content-rating.module.mjs +36 -36
  69. package/esm2022/lib/_collection/_common/user-image/user-image.component.mjs +62 -62
  70. package/esm2022/lib/_collection/_common/user-image/user-image.module.mjs +24 -24
  71. package/esm2022/lib/_collection/btn-page-back/btn-page-back.component.mjs +192 -192
  72. package/esm2022/lib/_collection/btn-page-back/btn-page-back.module.mjs +44 -44
  73. package/esm2022/lib/_collection/btn-page-back/btn-page-back.service.mjs +99 -99
  74. package/esm2022/lib/_collection/card-rating-comment/card-rating-comment.component.mjs +58 -58
  75. package/esm2022/lib/_collection/card-rating-comment/card-rating-comment.module.mjs +67 -67
  76. package/esm2022/lib/_collection/sliders-dynamic/sliders-dynamic.component.mjs +112 -112
  77. package/esm2022/lib/_collection/sliders-dynamic/sliders-dynamic.model.mjs +2 -2
  78. package/esm2022/lib/_collection/sliders-dynamic/sliders-dynamic.module.mjs +69 -69
  79. package/esm2022/lib/_collection-api.mjs +57 -57
  80. package/esm2022/lib/_constants/widget-content.constants.mjs +19 -19
  81. package/esm2022/lib/_directives/tooltip.directive.mjs +68 -68
  82. package/esm2022/lib/_models/common.model.mjs +2 -2
  83. package/esm2022/lib/_models/error.model.mjs +2 -2
  84. package/esm2022/lib/_pipes/highlight.pipe.mjs +24 -24
  85. package/esm2022/lib/_services/rating.service.mjs +89 -89
  86. package/esm2022/lib/_services/samuhik-charcha.service.mjs +29 -29
  87. package/esm2022/lib/_services/viewer-route-util.mjs +103 -103
  88. package/esm2022/lib/_services/widget-content.model.mjs +247 -247
  89. package/esm2022/lib/_services/widget-content.service.mjs +594 -594
  90. package/esm2022/lib/_shared/translate-loader.factory.mjs +9 -9
  91. package/esm2022/lib/app-toc-lib.module.mjs +499 -499
  92. package/esm2022/lib/collection.config.mjs +161 -161
  93. package/esm2022/lib/components/app-toc-analytics-tiles/app-toc-analytics-tiles.component.mjs +37 -37
  94. package/esm2022/lib/components/app-toc-banner/app-toc-banner.component.mjs +1436 -1436
  95. package/esm2022/lib/components/app-toc-cios-home/app-toc-cios-home.component.mjs +475 -475
  96. package/esm2022/lib/components/app-toc-cios-home/consent-dialog.component.mjs +119 -119
  97. package/esm2022/lib/components/app-toc-cohorts/app-toc-cohorts.component.mjs +80 -80
  98. package/esm2022/lib/components/app-toc-content-card/app-toc-content-card.component.mjs +249 -249
  99. package/esm2022/lib/components/app-toc-dialog-intro-video/app-toc-dialog-intro-video.component.mjs +39 -39
  100. package/esm2022/lib/components/app-toc-discussion/app-toc-discussion.component.mjs +58 -58
  101. package/esm2022/lib/components/app-toc-home/app-toc-home.component.mjs +2229 -2229
  102. package/esm2022/lib/components/app-toc-home-v2/app-toc-home-v2.component.mjs +2907 -2905
  103. package/esm2022/lib/components/app-toc-overview/app-toc-overview.component.mjs +157 -157
  104. package/esm2022/lib/components/app-toc-session-card/app-toc-session-card.component.mjs +48 -48
  105. package/esm2022/lib/components/app-toc-sessions/app-toc-sessions.component.mjs +47 -47
  106. package/esm2022/lib/components/app-toc-single-page/app-toc-single-page.component.mjs +766 -766
  107. package/esm2022/lib/components/completion-survey-form/completion-survey-form.component.mjs +243 -243
  108. package/esm2022/lib/components/create-batch-dialog/create-batch-dialog.component.mjs +116 -116
  109. package/esm2022/lib/components/enroll-language-dialogue/enroll-language-dialogue.component.mjs +44 -44
  110. package/esm2022/lib/components/enroll-profile-form/enroll-profile-form.component.mjs +1838 -1838
  111. package/esm2022/lib/components/enroll-questionnaire/enroll-questionnaire.component.mjs +236 -236
  112. package/esm2022/lib/components/knowledge-artifact-details/knowledge-artifact-details.component.mjs +213 -213
  113. package/esm2022/lib/components/non-relevent-feedback-dialog/non-relevent-feedback-dialog.component.mjs +36 -36
  114. package/esm2022/lib/components/public-survey-form/public-survey-form.component.mjs +256 -256
  115. package/esm2022/lib/components/survey-form-question/survey-form-question.component.mjs +133 -133
  116. package/esm2022/lib/components/survey-form-section/survey-form-section.component.mjs +36 -36
  117. package/esm2022/lib/models/app-toc-analytics.model.mjs +2 -2
  118. package/esm2022/lib/models/app-toc.model.mjs +38 -38
  119. package/esm2022/lib/models/auto-complete.model.mjs +2 -2
  120. package/esm2022/lib/models/card-content.model.mjs +13 -13
  121. package/esm2022/lib/models/content-strip-with-tabs.model.mjs +2 -2
  122. package/esm2022/lib/models/discussion-forum.model.mjs +14 -14
  123. package/esm2022/lib/models/goal.model.mjs +2 -2
  124. package/esm2022/lib/models/meta-tag.model.mjs +8 -8
  125. package/esm2022/lib/models/playlist.model.mjs +2 -2
  126. package/esm2022/lib/models/profile-revamp.model.mjs +2 -2
  127. package/esm2022/lib/models/rating.model.mjs +2 -2
  128. package/esm2022/lib/models/user-profile.model.mjs +21 -21
  129. package/esm2022/lib/resolvers/app-toc-cios-resolver.service.mjs +24 -24
  130. package/esm2022/lib/resolvers/app-toc-cios-user-enroll-resolver.service.mjs +24 -24
  131. package/esm2022/lib/resolvers/app-toc-content-read-resolver.service.mjs +60 -60
  132. package/esm2022/lib/resolvers/app-toc-ext-public-resolver.service.mjs +25 -25
  133. package/esm2022/lib/resolvers/app-toc-resolver.service.mjs +106 -106
  134. package/esm2022/lib/resolvers/config-resolver.service.mjs +25 -25
  135. package/esm2022/lib/resolvers/profile-resolver.service.mjs +25 -25
  136. package/esm2022/lib/resolvers/restricted-features-resolver.service.mjs +25 -25
  137. package/esm2022/lib/routes/app-toc-home/app-toc-home.component.mjs +51 -51
  138. package/esm2022/lib/routes/app-toc-home/app-toc-home.directive.mjs +16 -16
  139. package/esm2022/lib/routes/app-toc-home/app-toc-home.service.mjs +18 -18
  140. package/esm2022/lib/services/access-control.service.mjs +56 -56
  141. package/esm2022/lib/services/action.service.mjs +23 -23
  142. package/esm2022/lib/services/app-toc-v2.service.mjs +313 -243
  143. package/esm2022/lib/services/app-toc.service.mjs +1613 -1387
  144. package/esm2022/lib/services/certificate.service.mjs +69 -69
  145. package/esm2022/lib/services/discuss-utils.service.mjs +58 -58
  146. package/esm2022/lib/services/editor.service.mjs +34 -34
  147. package/esm2022/lib/services/load-check.service.mjs +21 -21
  148. package/esm2022/lib/services/loader.service.mjs +33 -33
  149. package/esm2022/lib/services/mobile-apps.service.mjs +67 -67
  150. package/esm2022/lib/services/netcore.service.mjs +56 -56
  151. package/esm2022/lib/services/nps-grid.service.mjs +31 -31
  152. package/esm2022/lib/services/otp.service.mjs +43 -43
  153. package/esm2022/lib/services/profile-v2.service.mjs +43 -43
  154. package/esm2022/lib/services/reset-ratings.service.mjs +19 -19
  155. package/esm2022/lib/services/resource-download-helper.service.mjs +64 -64
  156. package/esm2022/lib/services/timer.service.mjs +23 -23
  157. package/esm2022/lib/services/title-tag.service.mjs +71 -71
  158. package/esm2022/lib/services/user-profile.service.mjs +55 -55
  159. package/esm2022/lib/services/viewer-data.service.mjs +64 -64
  160. package/esm2022/lib/services/viewer-util.service.mjs +590 -500
  161. package/esm2022/lib/share-toc/share-toc/share-toc.component.mjs +291 -291
  162. package/esm2022/lib/share-toc/share-toc.module.mjs +119 -119
  163. package/esm2022/public-api.mjs +71 -70
  164. package/esm2022/sunbird-cb-toc.mjs +4 -4
  165. package/fesm2022/sunbird-cb-toc.mjs +24777 -24250
  166. package/fesm2022/sunbird-cb-toc.mjs.map +1 -1
  167. package/index.d.ts +5 -5
  168. package/lib/_collection/_common/attendance-card/attendance-card.component.d.ts +16 -16
  169. package/lib/_collection/_common/attendance-card/attendance-card.module.d.ts +31 -31
  170. package/lib/_collection/_common/attendance-helper/attendance-helper.component.d.ts +15 -15
  171. package/lib/_collection/_common/attendance-helper/attendance-helper.module.d.ts +20 -20
  172. package/lib/_collection/_common/avatar-photo/avatar-photo.component.d.ts +22 -22
  173. package/lib/_collection/_common/avatar-photo/avatar-photo.module.d.ts +15 -15
  174. package/lib/_collection/_common/certificate-dialog/certificate-dialog.component.d.ts +22 -22
  175. package/lib/_collection/_common/certificate-dialog/certificate-dialog.module.d.ts +22 -22
  176. package/lib/_collection/_common/certificate-dialog/svg-to-pdf.component.d.ts +9 -9
  177. package/lib/_collection/_common/confirm-dialog/confirm-dialog.component.d.ts +11 -11
  178. package/lib/_collection/_common/confirm-dialog/confirm-dialog.module.d.ts +12 -12
  179. package/lib/_collection/_common/connection-hover-card/connection-hover-card.component.d.ts +18 -18
  180. package/lib/_collection/_common/connection-hover-card/connection-hover.module.d.ts +14 -14
  181. package/lib/_collection/_common/connection-hover-card/connection-hover.servive.d.ts +11 -11
  182. package/lib/_collection/_common/connection-name/connection-name.component.d.ts +17 -17
  183. package/lib/_collection/_common/connection-name/connection-name.module.d.ts +14 -14
  184. package/lib/_collection/_common/connection-name/profile-v2.model.d.ts +199 -199
  185. package/lib/_collection/_common/content-progress/content-progress.component.d.ts +16 -16
  186. package/lib/_collection/_common/content-progress/content-progress.module.d.ts +10 -10
  187. package/lib/_collection/_common/content-rating-v2-dialog/content-rating-v2-dialog.component.d.ts +38 -38
  188. package/lib/_collection/_common/content-rating-v2-dialog/content-rating-v2-dialog.module.d.ts +19 -19
  189. package/lib/_collection/_common/content-toc/ai-tutor-confirm-popup/ai-tutor-confirm-popup.component.d.ts +11 -11
  190. package/lib/_collection/_common/content-toc/app-toc-about/app-toc-about.component.d.ts +183 -183
  191. package/lib/_collection/_common/content-toc/app-toc-assignment-viewer/app-toc-assignment-viewer.component.d.ts +41 -41
  192. package/lib/_collection/_common/content-toc/app-toc-assignment-viewerV2/app-toc-assignment-viewerV2.component.d.ts +54 -54
  193. package/lib/_collection/_common/content-toc/app-toc-batch-assignments/app-toc-batch-assignments.component.d.ts +47 -47
  194. package/lib/_collection/_common/content-toc/app-toc-content/app-toc-content.component.d.ts +49 -48
  195. package/lib/_collection/_common/content-toc/app-toc-content-card-v2/app-toc-content-card-v2.component.d.ts +171 -154
  196. package/lib/_collection/_common/content-toc/app-toc-content-card-v2-skeleton/app-toc-content-card-v2-skeleton.component.d.ts +8 -8
  197. package/lib/_collection/_common/content-toc/app-toc-reference-notes/app-toc-reference-notes.component.d.ts +16 -16
  198. package/lib/_collection/_common/content-toc/app-toc-session-card-new/app-toc-session-card-new.component.d.ts +40 -40
  199. package/lib/_collection/_common/content-toc/app-toc-sessions-new/app-toc-sessions-new.component.d.ts +21 -21
  200. package/lib/_collection/_common/content-toc/app-toc-teachers-notes/app-toc-teachers-notes.component.d.ts +45 -45
  201. package/lib/_collection/_common/content-toc/content-services/handle-claim.service.d.ts +10 -10
  202. package/lib/_collection/_common/content-toc/content-services/review-component-data.service.d.ts +10 -10
  203. package/lib/_collection/_common/content-toc/content-toc.component.d.ts +128 -128
  204. package/lib/_collection/_common/content-toc/content-toc.module.d.ts +51 -51
  205. package/lib/_collection/_common/content-toc/karma-points/karma-points.component.d.ts +29 -29
  206. package/lib/_collection/_common/content-toc/karma-points/karma-points.module.d.ts +9 -9
  207. package/lib/_collection/_common/content-toc/pipes/replace-nbsp.pipe.d.ts +7 -7
  208. package/lib/_collection/_common/content-toc/pipes/truncate.pipe.d.ts +7 -7
  209. package/lib/_collection/_common/content-toc/reviews-content/reviews-content.component.d.ts +28 -28
  210. package/lib/_collection/_common/content-toc/samuhik-charcha-content/samuhik-charcha-content/samuhik-charcha-content.component.d.ts +24 -24
  211. package/lib/_collection/_common/display-content-type/display-content-type.component.d.ts +14 -14
  212. package/lib/_collection/_common/display-content-type/display-content-type.module.d.ts +9 -9
  213. package/lib/_collection/_common/display-content-type-icon/display-content-type-icon.component.d.ts +12 -12
  214. package/lib/_collection/_common/display-content-type-icon/display-content-type-icon.module.d.ts +10 -10
  215. package/lib/_collection/_common/mark-as-complete/mark-as-complete.component.d.ts +22 -22
  216. package/lib/_collection/_common/mark-as-complete/mark-as-complete.model.d.ts +8 -8
  217. package/lib/_collection/_common/mark-as-complete/mark-as-complete.module.d.ts +18 -18
  218. package/lib/_collection/_common/pipe-content-route/pipe-content-route.module.d.ts +8 -8
  219. package/lib/_collection/_common/pipe-content-route/pipe-content-route.pipe.d.ts +15 -15
  220. package/lib/_collection/_common/player-brief/player-brief.component.d.ts +35 -35
  221. package/lib/_collection/_common/player-brief/player-brief.module.d.ts +19 -19
  222. package/lib/_collection/_common/rating-summary/rating-summary.component.d.ts +14 -14
  223. package/lib/_collection/_common/rating-summary/rating-summary.module.d.ts +13 -13
  224. package/lib/_collection/_common/skeleton-loader/skeleton-loader.component.d.ts +11 -11
  225. package/lib/_collection/_common/skeleton-loader/skeleton-loader.module.d.ts +11 -11
  226. package/lib/_collection/_common/tips-for-learner/tips-for-learner-card/tips-for-learner-card.component.d.ts +15 -15
  227. package/lib/_collection/_common/tips-for-learner/tips-for-learner.module.d.ts +10 -10
  228. package/lib/_collection/_common/toc-kpi-values/toc-kpi-values.component.d.ts +16 -16
  229. package/lib/_collection/_common/toc-kpi-values/toc-kpi-values.module.d.ts +11 -11
  230. package/lib/_collection/_common/user-autocomplete/user-autocomplete.component.d.ts +34 -34
  231. package/lib/_collection/_common/user-autocomplete/user-autocomplete.model.d.ts +17 -17
  232. package/lib/_collection/_common/user-autocomplete/user-autocomplete.module.d.ts +15 -15
  233. package/lib/_collection/_common/user-autocomplete/user-autocomplete.service.d.ts +15 -15
  234. package/lib/_collection/_common/user-content-rating/user-content-rating.component.d.ts +21 -21
  235. package/lib/_collection/_common/user-content-rating/user-content-rating.module.d.ts +12 -12
  236. package/lib/_collection/_common/user-image/user-image.component.d.ts +21 -21
  237. package/lib/_collection/_common/user-image/user-image.module.d.ts +9 -9
  238. package/lib/_collection/btn-page-back/btn-page-back.component.d.ts +47 -47
  239. package/lib/_collection/btn-page-back/btn-page-back.module.d.ts +14 -14
  240. package/lib/_collection/btn-page-back/btn-page-back.service.d.ts +22 -22
  241. package/lib/_collection/card-rating-comment/card-rating-comment.component.d.ts +19 -19
  242. package/lib/_collection/card-rating-comment/card-rating-comment.module.d.ts +15 -15
  243. package/lib/_collection/sliders-dynamic/sliders-dynamic.component.d.ts +25 -25
  244. package/lib/_collection/sliders-dynamic/sliders-dynamic.model.d.ts +21 -21
  245. package/lib/_collection/sliders-dynamic/sliders-dynamic.module.d.ts +18 -18
  246. package/lib/_collection-api.d.ts +34 -34
  247. package/lib/_constants/widget-content.constants.d.ts +7 -7
  248. package/lib/_directives/tooltip.directive.d.ts +17 -17
  249. package/lib/_models/common.model.d.ts +3 -3
  250. package/lib/_models/error.model.d.ts +5 -5
  251. package/lib/_pipes/highlight.pipe.d.ts +10 -10
  252. package/lib/_services/rating.service.d.ts +18 -18
  253. package/lib/_services/samuhik-charcha.service.d.ts +13 -13
  254. package/lib/_services/viewer-route-util.d.ts +8 -8
  255. package/lib/_services/widget-content.model.d.ts +515 -515
  256. package/lib/_services/widget-content.service.d.ts +101 -101
  257. package/lib/_shared/translate-loader.factory.d.ts +7 -7
  258. package/lib/app-toc-lib.module.d.ts +88 -88
  259. package/lib/collection.config.d.ts +159 -159
  260. package/lib/components/app-toc-analytics-tiles/app-toc-analytics-tiles.component.d.ts +17 -17
  261. package/lib/components/app-toc-banner/app-toc-banner.component.d.ts +225 -225
  262. package/lib/components/app-toc-cios-home/app-toc-cios-home.component.d.ts +78 -78
  263. package/lib/components/app-toc-cios-home/consent-dialog.component.d.ts +22 -22
  264. package/lib/components/app-toc-cohorts/app-toc-cohorts.component.d.ts +31 -31
  265. package/lib/components/app-toc-content-card/app-toc-content-card.component.d.ts +47 -47
  266. package/lib/components/app-toc-dialog-intro-video/app-toc-dialog-intro-video.component.d.ts +14 -14
  267. package/lib/components/app-toc-discussion/app-toc-discussion.component.d.ts +21 -21
  268. package/lib/components/app-toc-home/app-toc-home.component.d.ts +314 -314
  269. package/lib/components/app-toc-home-v2/app-toc-home-v2.component.d.ts +408 -408
  270. package/lib/components/app-toc-overview/app-toc-overview.component.d.ts +47 -47
  271. package/lib/components/app-toc-session-card/app-toc-session-card.component.d.ts +22 -22
  272. package/lib/components/app-toc-sessions/app-toc-sessions.component.d.ts +14 -14
  273. package/lib/components/app-toc-single-page/app-toc-single-page.component.d.ts +149 -149
  274. package/lib/components/completion-survey-form/completion-survey-form.component.d.ts +42 -42
  275. package/lib/components/create-batch-dialog/create-batch-dialog.component.d.ts +27 -27
  276. package/lib/components/enroll-language-dialogue/enroll-language-dialogue.component.d.ts +15 -15
  277. package/lib/components/enroll-profile-form/enroll-profile-form.component.d.ts +195 -195
  278. package/lib/components/enroll-questionnaire/enroll-questionnaire.component.d.ts +44 -44
  279. package/lib/components/knowledge-artifact-details/knowledge-artifact-details.component.d.ts +54 -54
  280. package/lib/components/non-relevent-feedback-dialog/non-relevent-feedback-dialog.component.d.ts +18 -18
  281. package/lib/components/public-survey-form/public-survey-form.component.d.ts +43 -43
  282. package/lib/components/survey-form-question/survey-form-question.component.d.ts +20 -20
  283. package/lib/components/survey-form-section/survey-form-section.component.d.ts +13 -13
  284. package/lib/models/app-toc-analytics.model.d.ts +152 -152
  285. package/lib/models/app-toc.model.d.ts +84 -84
  286. package/lib/models/auto-complete.model.d.ts +27 -27
  287. package/lib/models/card-content.model.d.ts +19 -19
  288. package/lib/models/content-strip-with-tabs.model.d.ts +44 -44
  289. package/lib/models/discussion-forum.model.d.ts +40 -40
  290. package/lib/models/goal.model.d.ts +22 -22
  291. package/lib/models/meta-tag.model.d.ts +6 -6
  292. package/lib/models/playlist.model.d.ts +23 -23
  293. package/lib/models/profile-revamp.model.d.ts +14 -14
  294. package/lib/models/rating.model.d.ts +17 -17
  295. package/lib/models/user-profile.model.d.ts +37 -37
  296. package/lib/resolvers/app-toc-cios-resolver.service.d.ts +12 -12
  297. package/lib/resolvers/app-toc-cios-user-enroll-resolver.service.d.ts +12 -12
  298. package/lib/resolvers/app-toc-content-read-resolver.service.d.ts +16 -16
  299. package/lib/resolvers/app-toc-ext-public-resolver.service.d.ts +12 -12
  300. package/lib/resolvers/app-toc-resolver.service.d.ts +16 -16
  301. package/lib/resolvers/config-resolver.service.d.ts +11 -11
  302. package/lib/resolvers/profile-resolver.service.d.ts +11 -11
  303. package/lib/resolvers/restricted-features-resolver.service.d.ts +11 -11
  304. package/lib/routes/app-toc-home/app-toc-home.component.d.ts +19 -19
  305. package/lib/routes/app-toc-home/app-toc-home.directive.d.ts +8 -8
  306. package/lib/routes/app-toc-home/app-toc-home.service.d.ts +8 -8
  307. package/lib/services/access-control.service.d.ts +29 -29
  308. package/lib/services/action.service.d.ts +9 -9
  309. package/lib/services/app-toc-v2.service.d.ts +16 -14
  310. package/lib/services/app-toc.service.d.ts +235 -177
  311. package/lib/services/certificate.service.d.ts +42 -42
  312. package/lib/services/discuss-utils.service.d.ts +33 -33
  313. package/lib/services/editor.service.d.ts +17 -17
  314. package/lib/services/load-check.service.d.ts +8 -8
  315. package/lib/services/loader.service.d.ts +16 -16
  316. package/lib/services/mobile-apps.service.d.ts +38 -38
  317. package/lib/services/netcore.service.d.ts +33 -33
  318. package/lib/services/nps-grid.service.d.ts +15 -15
  319. package/lib/services/otp.service.d.ts +20 -20
  320. package/lib/services/profile-v2.service.d.ts +20 -20
  321. package/lib/services/reset-ratings.service.d.ts +8 -8
  322. package/lib/services/resource-download-helper.service.d.ts +29 -29
  323. package/lib/services/timer.service.d.ts +9 -9
  324. package/lib/services/title-tag.service.d.ts +21 -21
  325. package/lib/services/user-profile.service.d.ts +24 -24
  326. package/lib/services/viewer-data.service.d.ts +58 -58
  327. package/lib/services/viewer-util.service.d.ts +76 -62
  328. package/lib/share-toc/share-toc/share-toc.component.d.ts +56 -56
  329. package/lib/share-toc/share-toc.module.d.ts +32 -32
  330. package/package.json +1 -1
  331. package/public-api.d.ts +56 -55
@@ -1,1387 +1,1613 @@
1
- import { Injectable } from '@angular/core';
2
- import { Subject, EMPTY, BehaviorSubject, of, throwError } from 'rxjs';
3
- import { NsContent } from '../_services/widget-content.model';
4
- import { NsContentConstants } from '../_constants/widget-content.constants';
5
- import { NsAppToc } from '../models/app-toc.model';
6
- // tslint:disable-next-line
7
- import _ from 'lodash';
8
- import { map, catchError } from 'rxjs/operators';
9
- import * as i0 from "@angular/core";
10
- import * as i1 from "@angular/common/http";
11
- import * as i2 from "@sunbird-cb/consumption";
12
- import * as i3 from "@sunbird-cb/utils-v2";
13
- import * as i4 from "../_services/widget-content.service";
14
- // TODO: move this in some common place
15
- const PROTECTED_SLAG_V8 = '/apis/protected/v8';
16
- const PROXY_SLAG_V8 = '/apis/proxies/v8';
17
- const API_END_POINTS = {
18
- BATCH_CREATE: `${PROXY_SLAG_V8}/learner/course/v1/batch/create`,
19
- CONTENT_PARENTS: `${PROTECTED_SLAG_V8}/content/parents`,
20
- CONTENT_NEXT: `${PROTECTED_SLAG_V8}/content/next`,
21
- CONTENT_HISTORYV2: `/apis/proxies/v8/read/content-progres`,
22
- CONTENT_PARENT: (contentId) => `${PROTECTED_SLAG_V8}/content/${contentId}/parent`,
23
- CONTENT_AUTH_PARENT: (contentId, rootOrg, org) => `/apis/authApi/action/content/parent/hierarchy/${contentId}?rootOrg=${rootOrg}&org=${org}`,
24
- COHORTS: (cohortType, contentId) => `${PROTECTED_SLAG_V8}/cohorts/${cohortType}/${contentId}`,
25
- EXTERNAL_CONTENT: (contentId) => `${PROTECTED_SLAG_V8}/content/external-access/${contentId}`,
26
- COHORTS_GROUP_USER: (groupId) => `${PROTECTED_SLAG_V8}/cohorts/${groupId}`,
27
- RELATED_RESOURCE: (contentId, contentType) => `${PROTECTED_SLAG_V8}/khub/fetchRelatedResources/${contentId}/${contentType}`,
28
- POST_ASSESSMENT: (contentId) => `${PROTECTED_SLAG_V8}/user/evaluate/post-assessment/${contentId}`,
29
- GET_CONTENT: (contentId) => `${PROXY_SLAG_V8}/action/content/v3/read/${contentId}`,
30
- CERT_DOWNLOAD: (certId) => `${PROTECTED_SLAG_V8}/cohorts/course/batch/cert/download/${certId}`,
31
- SERVER_DATE: 'apis/public/v8/systemDate',
32
- SHARE_CONTENT: '/apis/proxies/v8/user/v1/content/recommend',
33
- GET_FORM_BYID: (formId) => `apis/proxies/v8/forms/v2/getFormById?formId=${formId}`,
34
- // SUBMIT_FORM: `/apis/proxies/v8/forms/v1/saveFormSubmit`,
35
- SUBMIT_FORM: `apis/proxies/v8/forms/v2/saveFormSubmit`,
36
- GET_FORM_BYID_PUBLIC: (formId) => `apis/public/v8/public/forms/v2/getFormById?formId=${formId}`,
37
- SUBMIT_FORM_PUBLIC: `apis/public/v8/public/forms/v2/saveFormSubmit`,
38
- // get answers for form
39
- GET_APPLICATIONS_BY_ID: (formId, contextId) => `/apis/proxies/v8/forms/v2/getApplicationsById?formId=${formId}&contextId=${contextId}`,
40
- AI_RESOURCE_VTT_FILE: `${PROXY_SLAG_V8}/chatbot/v3/transcoder/stats`,
41
- // GET_FORM_BYID: (formId: string) => `apis/proxies/v8/forms/getFormById?id=${formId}`,
42
- PRE_ENROLLMENT_STATE_READ: `/apis/proxies/v8/content/v2/state/read`,
43
- CREATE_RESOURCE: `apis/proxies/v8/action/content/v3/create`,
44
- READ_RESOURCE: `apis/proxies/v8/action/content/v3/`,
45
- UPLOAD_FILE: `apis/proxies/v8/upload/action/content/v3/`,
46
- UPDATE_RESOURCE: `apis/proxies/v8/action/content/v3/update`,
47
- SEARCH: `apis/proxies/v8/assignment/v1/search`,
48
- SUBMIT_DRAFT_ASSIGNMENT: `apis/proxies/v8/assignment/v1/submitDraft`,
49
- SUBMIT_ASSIGNMENT: `apis/proxies/v8/assignment/v1/submit`,
50
- ASSIGNMENT_STATUS: `apis/proxies/v8/forms/v2/submissions/search`,
51
- UPLOAD_ASSIGNMENT: `apis/proxies/v8/storage/v1/bp/assignment/answer`,
52
- READ_ASSIGNMENT: `apis/proxies/v8/storage/v1/bp/assignment/answer/read/file`,
53
- NOTIFY_ASSIGNMENT_SUBMISSION: `apis/proxies/v8/v1/notifyAssignment/submit`,
54
- };
55
- export class AppTocService {
56
- constructor(http, contentLangSvc, configSvc, widgetSvc) {
57
- this.http = http;
58
- this.contentLangSvc = contentLangSvc;
59
- this.configSvc = configSvc;
60
- this.widgetSvc = widgetSvc;
61
- this.analyticsReplaySubject = new Subject();
62
- this.analyticsFetchStatus = 'none';
63
- this.batchReplaySubject = new Subject();
64
- this.setBatchDataSubject = new Subject();
65
- this.getSelectedBatch = new Subject();
66
- this.setWFDataSubject = new Subject();
67
- this.resumeData = new Subject();
68
- this.showSubtitleOnBanners = false;
69
- this.canShowDescription = false;
70
- this.resumeDataSubscription = null;
71
- this.primaryCategory = NsContent.EPrimaryCategory;
72
- this.updateReviews = new BehaviorSubject(false);
73
- this.updateReviewsObservable = this.updateReviews.asObservable();
74
- this.serverDate = new BehaviorSubject('');
75
- this.currentServerDate = this.serverDate.asObservable();
76
- this.contentLoader = new BehaviorSubject(false);
77
- this.contentLoader$ = this.contentLoader.asObservable();
78
- this.getPageScroll = new BehaviorSubject(true);
79
- this.updatePageScroll = this.getPageScroll.asObservable();
80
- this.hashmap = {};
81
- this.hashmapUpdated = new BehaviorSubject(null);
82
- this.hashmapUpdated$ = this.hashmapUpdated.asObservable();
83
- this.transriptionDataSubject = new BehaviorSubject(null); // Start with null
84
- this.transcriptionData$ = this.transriptionDataSubject.asObservable();
85
- this.transriptionActiveLanguageDataObject = new BehaviorSubject(null);
86
- this.transriptionActiveLanguageDataObject$ = this.transriptionActiveLanguageDataObject.asObservable();
87
- this.transriptionIdentifier = new Subject(); // Start with null
88
- this.changeTranscriptionLanguageEvent = new Subject();
89
- this.playTranscriptionVideo = new Subject();
90
- // this resume data subscription is for on load
91
- this.resumeDataSubscription = this.resumeData.subscribe((_dataResult) => {
92
- });
93
- }
94
- get subtitleOnBanners() {
95
- return this.showSubtitleOnBanners;
96
- }
97
- set subtitleOnBanners(val) {
98
- this.showSubtitleOnBanners = val;
99
- }
100
- get showDescription() {
101
- return this.canShowDescription;
102
- }
103
- set showDescription(val) {
104
- this.canShowDescription = val;
105
- }
106
- updateBatchData() {
107
- this.batchReplaySubject.next();
108
- }
109
- setBatchData(data) {
110
- this.setBatchDataSubject.next(data);
111
- }
112
- setWFData(data) {
113
- this.setWFDataSubject.next(data);
114
- }
115
- updateResumaData(data) {
116
- this.resumeData.next(data);
117
- }
118
- changeUpdateReviews(state) {
119
- this.updateReviews.next(state);
120
- }
121
- getSelectedBatchData(data) {
122
- this.getSelectedBatch.next(data);
123
- }
124
- changeServerDate(state) {
125
- this.serverDate.next(state);
126
- }
127
- mapSessionCompletionPercentage(batchData, resumeDataPass) {
128
- if (resumeDataPass && resumeDataPass.length) {
129
- if (resumeDataPass && resumeDataPass.length && batchData.content && batchData.content.length) {
130
- this.sessionCompletionPercentage(batchData, resumeDataPass);
131
- }
132
- }
133
- else {
134
- this.resumeDataSubscription = this.resumeData.subscribe((dataResult) => {
135
- if (dataResult && dataResult.length && batchData.content && batchData.content.length) {
136
- this.sessionCompletionPercentage(batchData, dataResult);
137
- }
138
- }, () => {
139
- this.contentLoader.next(false);
140
- });
141
- }
142
- }
143
- sessionCompletionPercentage(batchData, resumeDataPass) {
144
- if (resumeDataPass && resumeDataPass.length) {
145
- if (batchData && batchData.content[0] &&
146
- batchData.content[0].batchAttributes &&
147
- batchData.content[0].batchAttributes.sessionDetails_v2) {
148
- batchData.content[0].batchAttributes.sessionDetails_v2.map((sd) => {
149
- const foundContent = resumeDataPass.find((el) => el.contentId === sd.sessionId);
150
- if (foundContent) {
151
- sd.completionPercentage = foundContent.completionPercentage;
152
- sd.completionStatus = foundContent.status;
153
- sd.lastCompletedTime = foundContent.lastCompletedTime;
154
- }
155
- });
156
- this.contentLoader.next(false);
157
- }
158
- }
159
- }
160
- showStartButton(content) {
161
- const status = {
162
- show: false,
163
- msg: '',
164
- };
165
- if (content) {
166
- if (content.artifactUrl && content.artifactUrl.match(/youtu(.)?be/gi) &&
167
- this.configSvc.userProfile &&
168
- this.configSvc.userProfile.country === 'China') {
169
- status.show = false;
170
- status.msg = 'youtubeForbidden';
171
- return status;
172
- }
173
- if (content.resourceType !== 'Certification') {
174
- status.show = true;
175
- return status;
176
- }
177
- }
178
- return status;
179
- }
180
- initData(data, needResumeData = false) {
181
- let content = null;
182
- let errorCode = null;
183
- this.contentLoader.next(true);
184
- if (data.content && data.content.data && data.content.data.identifier) {
185
- content = data.content.data;
186
- if (needResumeData) {
187
- this.resumeDataSubscription = this.resumeData.subscribe((dataResult) => {
188
- if (dataResult && dataResult.length) {
189
- this.contentLoader.next(true);
190
- this.mapCompletionPercentage(content, dataResult);
191
- }
192
- }, () => {
193
- // tslint:disable-next-line: no-console
194
- console.log('error on resumeDataSubscription');
195
- });
196
- }
197
- else {
198
- this.contentLoader.next(false);
199
- }
200
- }
201
- else {
202
- this.contentLoader.next(false);
203
- if (data.error) {
204
- errorCode = NsAppToc.EWsTocErrorCode.API_FAILURE;
205
- }
206
- else {
207
- errorCode = NsAppToc.EWsTocErrorCode.NO_DATA;
208
- }
209
- }
210
- // this.contentLoader.next(false)
211
- return {
212
- content,
213
- errorCode,
214
- };
215
- }
216
- mapCompletionPercentage(content, dataResult) {
217
- if (content && content.children) {
218
- content.children.map(child => {
219
- const foundContent = dataResult.find((el) => el.contentId === child.identifier);
220
- if (foundContent) {
221
- child.completionPercentage = foundContent.completionPercentage || foundContent.progress;
222
- child.completionStatus = foundContent.status;
223
- }
224
- else {
225
- this.mapCompletionPercentage(child, dataResult);
226
- }
227
- });
228
- this.contentLoader.next(false);
229
- }
230
- else {
231
- this.contentLoader.next(false);
232
- }
233
- }
234
- mapModuleCount(content) {
235
- if (content && content.children) {
236
- content.children.map(child => {
237
- if (child.primaryCategory === NsContent.EPrimaryCategory.MODULE) {
238
- content['moduleCount'] = content['moduleCount'] ? content['moduleCount'] + 1 : 1;
239
- }
240
- if (child.primaryCategory === NsContent.EPrimaryCategory.COURSE) {
241
- this.mapModuleCount(child);
242
- }
243
- });
244
- }
245
- }
246
- getMimeType(content, identifier) {
247
- if (content.identifier === identifier) {
248
- return content.mimeType;
249
- }
250
- if (content && content.children) {
251
- if (content.children.length === 0) {
252
- // if (content.children[0].identifier === identifier) {
253
- // return content.mimeType
254
- // }
255
- // big blunder in data
256
- // this.logger.log(content.identifier, 'Wrong mimetypes for resume')
257
- return content.mimeType;
258
- }
259
- const flatList = [];
260
- const getAllItemsPerChildren = (item) => {
261
- flatList.push(item);
262
- if (item.children) {
263
- return item.children.map((i) => getAllItemsPerChildren(i));
264
- }
265
- return;
266
- };
267
- getAllItemsPerChildren(content);
268
- const chld = _.first(_.filter(flatList, { identifier }));
269
- return (chld && chld.mimeType) || '';
270
- }
271
- // return chld.mimeType
272
- return NsContent.EMimeTypes.UNKNOWN;
273
- }
274
- getTocStructure(content, tocStructure) {
275
- if (content &&
276
- !(content.primaryCategory === this.primaryCategory.RESOURCE
277
- // || content.primaryCategory === this.primaryCategory.KNOWLEDGE_ARTIFACT)
278
- || content.primaryCategory === this.primaryCategory.PRACTICE_RESOURCE
279
- || content.primaryCategory === this.primaryCategory.FINAL_ASSESSMENT
280
- || content.primaryCategory === this.primaryCategory.OFFLINE_SESSION)) {
281
- if (content.primaryCategory === NsContent.EPrimaryCategory.COURSE) {
282
- tocStructure.course += 1;
283
- }
284
- else if (content.primaryCategory === NsContent.EPrimaryCategory.MODULE) {
285
- tocStructure.learningModule += 1;
286
- }
287
- _.each(content.children, child => {
288
- // tslint:disable-next-line: no-parameter-reassignment
289
- tocStructure = this.getTocStructure(child, tocStructure);
290
- });
291
- }
292
- else if (content &&
293
- (content.primaryCategory === NsContent.EPrimaryCategory.RESOURCE
294
- // || content.contentType === 'Knowledge Artifact'
295
- || content.primaryCategory === NsContent.EPrimaryCategory.PRACTICE_RESOURCE
296
- || content.primaryCategory === NsContent.EPrimaryCategory.FINAL_ASSESSMENT
297
- || content.primaryCategory === NsContent.EPrimaryCategory.OFFLINE_SESSION)) {
298
- switch (content.mimeType) {
299
- // case NsContent.EMimeTypes.HANDS_ON:
300
- // tocStructure.handsOn += 1
301
- // break
302
- case NsContent.EMimeTypes.MP3:
303
- tocStructure.podcast += 1;
304
- break;
305
- case NsContent.EMimeTypes.MP4:
306
- case NsContent.EMimeTypes.M3U8:
307
- case NsContent.EMimeTypes.YOUTUBE:
308
- tocStructure.video += 1;
309
- break;
310
- // case NsContent.EMimeTypes.INTERACTION:
311
- // tocStructure.interactiveVideo += 1
312
- // break
313
- case NsContent.EMimeTypes.PDF:
314
- tocStructure.pdf += 1;
315
- break;
316
- // case NsContent.EMimeTypes.HTML:
317
- case NsContent.EMimeTypes.TEXT_WEB:
318
- tocStructure.webPage += 1;
319
- break;
320
- case NsContent.EMimeTypes.SURVEY:
321
- tocStructure.survey += 1;
322
- break;
323
- case NsContent.EMimeTypes.QUIZ:
324
- case NsContent.EMimeTypes.APPLICATION_JSON:
325
- // if (content.resourceType === 'Assessment') {
326
- tocStructure.assessment += 1;
327
- // } else {
328
- // tocStructure.quiz += 1
329
- // }
330
- break;
331
- case NsContent.EMimeTypes.OFFLINE_SESSION:
332
- // if (content.resourceType === 'Assessment') {
333
- tocStructure.offlineSession += 1;
334
- // } else {
335
- // tocStructure.quiz += 1
336
- // }
337
- break;
338
- case NsContent.EMimeTypes.PRACTICE_RESOURCE:
339
- if (content.primaryCategory === this.primaryCategory.PRACTICE_RESOURCE) {
340
- tocStructure.practiceTest += 1;
341
- }
342
- else if (content.primaryCategory === this.primaryCategory.FINAL_ASSESSMENT) {
343
- tocStructure.finalTest += 1;
344
- }
345
- break;
346
- // case NsContent.EMimeTypes.WEB_MODULE:
347
- // tocStructure.webModule += 1
348
- // break
349
- case NsContent.EMimeTypes.ZIP2:
350
- case NsContent.EMimeTypes.ZIP:
351
- tocStructure.interactivecontent += 1;
352
- break;
353
- // case NsContent.EMimeTypes.YOUTUBE:
354
- // tocStructure.youtube += 1
355
- // break
356
- default:
357
- tocStructure.other += 1;
358
- break;
359
- }
360
- return tocStructure;
361
- }
362
- return tocStructure;
363
- }
364
- filterToc(content, filterCategory = NsContent.EFilterCategory.ALL) {
365
- if (content.primaryCategory === NsContent.EPrimaryCategory.RESOURCE
366
- // || content.contentType === 'Knowledge Artifact'
367
- || content.primaryCategory === NsContent.EPrimaryCategory.PRACTICE_RESOURCE
368
- || content.primaryCategory === NsContent.EPrimaryCategory.FINAL_ASSESSMENT
369
- || content.primaryCategory === NsContent.EPrimaryCategory.OFFLINE_SESSION) {
370
- return this.filterUnitContent(content, filterCategory) ? content : null;
371
- }
372
- const filteredChildren = _.map(_.get(content, 'children'), childContent => this.filterToc(childContent, filterCategory))
373
- .filter(unitContent => Boolean(unitContent));
374
- if (filteredChildren && filteredChildren.length) {
375
- return {
376
- ...content,
377
- children: filteredChildren,
378
- };
379
- }
380
- return null;
381
- }
382
- filterUnitContent(content, filterCategory = NsContent.EFilterCategory.ALL) {
383
- switch (filterCategory) {
384
- case NsContent.EFilterCategory.LEARN:
385
- return (!NsContentConstants.VALID_PRACTICE_RESOURCES.has(content.resourceType) &&
386
- !NsContentConstants.VALID_ASSESSMENT_RESOURCES.has(content.resourceType));
387
- case NsContent.EFilterCategory.PRACTICE:
388
- return NsContentConstants.VALID_PRACTICE_RESOURCES.has(content.resourceType);
389
- case NsContent.EFilterCategory.ASSESS:
390
- return NsContentConstants.VALID_ASSESSMENT_RESOURCES.has(content.resourceType);
391
- case NsContent.EFilterCategory.ALL:
392
- default:
393
- return true;
394
- }
395
- }
396
- fetchContentAnalyticsClientData(contentId) {
397
- if (this.analyticsFetchStatus !== 'fetching' && this.analyticsFetchStatus !== 'done') {
398
- this.getContentAnalyticsClient(contentId);
399
- }
400
- }
401
- getContentAnalyticsClient(contentId) {
402
- this.analyticsFetchStatus = 'fetching';
403
- const url = `${PROXY_SLAG_V8}/LA/api/la/contentanalytics?content_id=${contentId}&type=course`;
404
- this.http.get(url).subscribe((result) => {
405
- this.analyticsFetchStatus = 'done';
406
- this.analyticsReplaySubject.next(result);
407
- }, () => {
408
- this.analyticsReplaySubject.next(null);
409
- this.analyticsFetchStatus = 'done';
410
- });
411
- }
412
- fetchContentAnalyticsData(contentId) {
413
- if (this.analyticsFetchStatus !== 'fetching' && this.analyticsFetchStatus !== 'done') {
414
- this.getContentAnalytics(contentId);
415
- }
416
- }
417
- getContentAnalytics(contentId) {
418
- this.analyticsFetchStatus = 'fetching';
419
- // tslint:disable-next-line: max-line-length
420
- const url = `${PROXY_SLAG_V8}/LA/LA/api/Users?refinementfilter=${encodeURIComponent('"source":["iGot","Learning Hub"]')}$${encodeURIComponent(`"courseCode": ["${contentId}"]`)}`;
421
- this.http.get(url).subscribe((result) => {
422
- this.analyticsFetchStatus = 'done';
423
- this.analyticsReplaySubject.next(result);
424
- }, () => {
425
- this.analyticsReplaySubject.next(null);
426
- this.analyticsFetchStatus = 'done';
427
- });
428
- }
429
- clearAnalyticsData() {
430
- if (this.analyticsReplaySubject) {
431
- this.analyticsReplaySubject.unsubscribe();
432
- }
433
- }
434
- fetchContentParents(contentId) {
435
- // return this.http.get<NsContent.IContentMinimal[]>(
436
- // `${API_END_POINTS.CONTENT_PARENTS}/${contentId}`,
437
- // )
438
- if (contentId) { }
439
- return EMPTY;
440
- }
441
- fetchContentWhatsNext(contentId, contentType) {
442
- if (contentType) {
443
- return this.http.get(`${API_END_POINTS.CONTENT_NEXT}/${contentId}?contentType=${contentType}`);
444
- }
445
- return this.http.get(`${API_END_POINTS.CONTENT_NEXT}/${contentId}?ts=${new Date().getTime()}`);
446
- }
447
- fetchMoreLikeThisPaid(contentId) {
448
- return this.http.get(`${API_END_POINTS.CONTENT_NEXT}/${contentId}?exclusiveContent=true&ts=${new Date().getTime()}`);
449
- }
450
- fetchMoreLikeThisFree(contentId) {
451
- return this.http.get(`${API_END_POINTS.CONTENT_NEXT}/${contentId}?exclusiveContent=false&ts=${new Date().getTime()}`);
452
- }
453
- fetchContentCohorts(cohortType, contentId) {
454
- return this.http.get(API_END_POINTS.COHORTS(cohortType, contentId), {
455
- headers: { rootOrg: this.configSvc.rootOrg || '', org: this.configSvc.org ? this.configSvc.org[0] : '' },
456
- });
457
- }
458
- fetchExternalContentAccess(contentId) {
459
- return this.http.get(API_END_POINTS.EXTERNAL_CONTENT(contentId));
460
- }
461
- fetchCohortGroupUsers(groupId) {
462
- return this.http.get(API_END_POINTS.COHORTS_GROUP_USER(groupId));
463
- }
464
- fetchMoreLikeThis(contentId, contentType) {
465
- return this.http.get(API_END_POINTS.RELATED_RESOURCE(contentId, contentType));
466
- }
467
- fetchPostAssessmentStatus(contentId) {
468
- return this.http.get(API_END_POINTS.POST_ASSESSMENT(contentId));
469
- }
470
- fetchGetContentData(contentId) {
471
- let url = '';
472
- const forPreview = window.location.href.includes('/public/') || window.location.href.includes('&preview=true');
473
- if (!forPreview) {
474
- return this.http.get(API_END_POINTS.GET_CONTENT(contentId));
475
- }
476
- if (window.location.href.includes('editMode=true') && window.location.href.includes('_rc')) {
477
- url = `/apis/proxies/v8/action/content/v3/read/${contentId}`;
478
- }
479
- else {
480
- url = `/api/content/v1/read/${contentId}`;
481
- }
482
- return this.http.get(url);
483
- }
484
- fetchContentParent(contentId, data, forPreview = false) {
485
- return this.http.post(forPreview
486
- ? API_END_POINTS.CONTENT_AUTH_PARENT(contentId, this.configSvc.rootOrg || '', this.configSvc.org ? this.configSvc.org[0] : '')
487
- : API_END_POINTS.CONTENT_PARENT(contentId), data);
488
- }
489
- createBatch(batchData) {
490
- return this.http.post(API_END_POINTS.BATCH_CREATE, { request: batchData });
491
- }
492
- async mapCompletionPercentageProgram(content, enrolmentList, collectionId) {
493
- this.contentLoader.next(true);
494
- let totalCount = 0;
495
- let leafnodeCount = 0;
496
- let completedLeafNodes = [];
497
- let firstUncompleteCourse = '';
498
- let inprogressDataCheck = [];
499
- if (content && content.children) {
500
- leafnodeCount = content.leafNodesCount;
501
- this.contentLoader.next(true);
502
- const foundParentContent = this.findEnrolmentByCollectionId(enrolmentList, collectionId || content.identifier);
503
- if (foundParentContent && foundParentContent.completionPercentage === 100) {
504
- await this.mapCompletionChildPercentageProgram(content);
505
- totalCount = content.leafNodesCount;
506
- }
507
- else {
508
- if (content?.primaryCategory !== NsContent.EPrimaryCategory.COURSE) {
509
- for (let i = 0; i < content.children.length; i += 1) {
510
- // content.children.forEach(async (parentChild,index) => {
511
- const parentChild = content.children[i];
512
- if (parentChild.primaryCategory === NsContent.EPrimaryCategory.COURSE) {
513
- const foundContent = this.findEnrolmentByCollectionId(enrolmentList, parentChild?.identifier);
514
- // tslint:disable-next-line: max-line-length
515
- // totalCount = foundContent && foundContent.completionPercentage ? totalCount + foundContent.completionPercentage : totalCount + 0
516
- // content.completionPercentage = Math.round(totalCount / leafnodeCount)
517
- if (foundContent && foundContent.completionPercentage === 100) {
518
- this.contentLoader.next(true);
519
- totalCount = totalCount += parentChild.leafNodesCount;
520
- completedLeafNodes = [...completedLeafNodes, ...parentChild.leafNodes];
521
- if (foundContent.issuedCertificates.length > 0) {
522
- const certificate = foundContent.issuedCertificates.sort((a, b) => new Date(a.lastIssuedOn).getTime() - new Date(b.lastIssuedOn).getTime());
523
- const certId = certificate[0].identifier;
524
- parentChild.issuedCertificatesId = certId;
525
- // const certData: any = await this.dowonloadCertificate(certId).toPromise().catch(_error => {
526
- // this.contentLoader.next(false)
527
- // })
528
- // if (certData && certData.result) {
529
- // parentChild.issuedCertificatesSVG = certData.result.printUri
530
- // }
531
- this.contentLoader.next(false);
532
- }
533
- parentChild.completionPercentage = 100;
534
- parentChild.completionStatus = 2;
535
- await this.mapCompletionChildPercentageProgram(parentChild);
536
- }
537
- else {
538
- if (foundContent) {
539
- this.contentLoader.next(true);
540
- const language = this.contentLangSvc.getContentLanguage(parentChild);
541
- const req = {
542
- request: {
543
- batchId: foundContent.batch.batchId,
544
- userId: foundContent.userId,
545
- language: language,
546
- courseId: foundContent.collectionId,
547
- contentIds: [],
548
- fields: [
549
- 'progressdetails',
550
- ],
551
- },
552
- };
553
- firstUncompleteCourse = (parentChild.completionPercentage === 0 || !parentChild.completionPercentage) &&
554
- !firstUncompleteCourse ? parentChild : firstUncompleteCourse;
555
- inprogressDataCheck = inprogressDataCheck;
556
- await this.fetchContentHistoryV2(req).toPromise().then((progressdata) => {
557
- const data = progressdata;
558
- if (data.result && data?.result?.contentList?.length > 0) {
559
- const completedCount = data.result.contentList.filter((ele) => ele.progress === 100);
560
- this.checkCompletedLeafnodes(completedLeafNodes, completedCount);
561
- totalCount = completedLeafNodes.length;
562
- inprogressDataCheck = [...inprogressDataCheck, ...data.result.contentList];
563
- // inprogressDataCheck = inprogressDataCheck ? inprogressDataCheck : data.result.contentList
564
- this.updateResumaData(inprogressDataCheck);
565
- this.mapCompletionPercentage(parentChild, data.result.contentList);
566
- this.mapModuleCount(parentChild);
567
- }
568
- else {
569
- this.mapModuleCount(parentChild);
570
- }
571
- return progressdata;
572
- });
573
- this.contentLoader.next(false);
574
- }
575
- }
576
- }
577
- // else {
578
- // if (content.primaryCategory !== NsContent.EPrimaryCategory.BLENDED_PROGRAM) {
579
- // this.contentLoader.next(true)
580
- // const foundContent = enrolmentList && enrolmentList.find((el: any) => el.collectionId === content.identifier)
581
- // if (foundContent) {
582
- // const req = {
583
- // request: {
584
- // batchId: foundContent.batch.batchId,
585
- // userId: foundContent.userId,
586
- // courseId: foundContent.collectionId,
587
- // contentIds: [],
588
- // fields: [
589
- // 'progressdetails',
590
- // ],
591
- // },
592
- // }
593
- // await this.fetchContentHistoryV2(req).toPromise().then((progressdata: any) => {
594
- // const data: any = progressdata
595
- // if (data.result && data.result.contentList.length > 0) {
596
- // const completedCount = data.result.contentList.filter((ele: any) => ele.progress === 100)
597
- // this.checkCompletedLeafnodes(completedLeafNodes, completedCount)
598
- // totalCount = completedLeafNodes.length
599
- // inprogressDataCheck = inprogressDataCheck ? inprogressDataCheck : data.result.contentList
600
- // this.updateResumaData(inprogressDataCheck)
601
- // this.mapCompletionPercentage(content, data.result.contentList)
602
- // }
603
- // this.contentLoader.next(false)
604
- // return progressdata
605
- // })
606
- // }
607
- // this.contentLoader.next(false)
608
- // }
609
- // }
610
- this.contentLoader.next(false);
611
- }
612
- }
613
- if (content.primaryCategory === NsContent.EPrimaryCategory.BLENDED_PROGRAM
614
- || content.primaryCategory === NsContent.EPrimaryCategory.COURSE
615
- || content.primaryCategory === NsContent.EPrimaryCategory.STANDALONE_ASSESSMENT
616
- || content.primaryCategory === NsContent.EPrimaryCategory.CURATED_PROGRAM) {
617
- // this.mapCompletionPercentage(content, this.resumeData)
618
- const foundParentContent = this.findEnrolmentByCollectionId(enrolmentList, collectionId || content?.identifier);
619
- const language = this.contentLangSvc.getContentLanguage(content);
620
- const req = {
621
- request: {
622
- batchId: foundParentContent?.batch?.batchId,
623
- userId: foundParentContent?.userId,
624
- courseId: foundParentContent?.collectionId,
625
- language: language,
626
- contentIds: [],
627
- fields: [
628
- 'progressdetails',
629
- ],
630
- },
631
- };
632
- await this.fetchContentHistoryV2(req).toPromise().then((progressdata) => {
633
- const data = progressdata;
634
- if (data && data.result && data.result.contentList.length > 0) {
635
- const completedCount = data.result.contentList.filter((ele) => ele.progress === 100);
636
- this.checkCompletedLeafnodes(completedLeafNodes, completedCount);
637
- totalCount = completedLeafNodes.length;
638
- inprogressDataCheck = [...inprogressDataCheck, ...data.result.contentList];
639
- // inprogressDataCheck = inprogressDataCheck ? inprogressDataCheck : data.result.contentList
640
- this.updateResumaData(inprogressDataCheck);
641
- this.mapCompletionPercentage(content, data.result.contentList);
642
- }
643
- this.contentLoader.next(false);
644
- return progressdata;
645
- });
646
- }
647
- if (inprogressDataCheck && inprogressDataCheck.length === 0 && firstUncompleteCourse) {
648
- const firstChildData = this.widgetSvc.getFirstChildInHierarchy(firstUncompleteCourse);
649
- const childEnrollmentData = enrolmentList.find((el) => el.collectionId === firstUncompleteCourse.identifier);
650
- const resumeData = [{
651
- contentId: firstChildData.identifier,
652
- batchId: childEnrollmentData && childEnrollmentData.batchId,
653
- completedCount: 1,
654
- completionPercentage: 0.0,
655
- progress: 0,
656
- viewCount: 1,
657
- courseId: childEnrollmentData && childEnrollmentData.courseId,
658
- collectionId: childEnrollmentData && childEnrollmentData.courseId,
659
- status: 1,
660
- }];
661
- inprogressDataCheck = resumeData;
662
- this.updateResumaData(inprogressDataCheck);
663
- }
664
- }
665
- // const parentContent = enrolmentList.find((el: any) => el.collectionId === content.identifier)
666
- // if (!parentContent.completionPercentage) {
667
- const calculatedPct = Math.floor((totalCount / leafnodeCount) * 100);
668
- content.completionPercentage = isNaN(calculatedPct) ? 0 : calculatedPct;
669
- content.completionStatus = content.completionPercentage >= 100 ? 2 : (content.completionPercentage > 0 ? 1 : 0);
670
- if (content.completionPercentage === 100 && inprogressDataCheck && inprogressDataCheck.length === 0 && !firstUncompleteCourse) {
671
- const firstChildData = this.widgetSvc.getFirstChildInHierarchy(content);
672
- const childEnrollmentData = enrolmentList.find((el) => el.collectionId === content.children[0].identifier);
673
- const resumeData = [{
674
- contentId: firstChildData.identifier,
675
- batchId: childEnrollmentData && childEnrollmentData.batchId,
676
- completedCount: 1,
677
- completionPercentage: 100,
678
- progress: 2,
679
- viewCount: 1,
680
- courseId: childEnrollmentData && childEnrollmentData.courseId,
681
- collectionId: childEnrollmentData && childEnrollmentData.courseId,
682
- status: 2,
683
- }];
684
- inprogressDataCheck = resumeData;
685
- this.updateResumaData(inprogressDataCheck);
686
- }
687
- // // } else {
688
- // content.completionPercentage = parentContent.completionPercentage
689
- // // }
690
- // })
691
- // this.mapModuleDurationAndProgress(content, content)
692
- this.callHirarchyProgressHashmap(content);
693
- this.checkModuleWiseData(content);
694
- // Compute milestone locking AFTER progress data is populated
695
- if (content.courseCategory === 'Learning Pathway') {
696
- this.computeMilestoneLockingStatus();
697
- // Ensure hashmap updates are published for change detection
698
- this.hashmap = { ...this.hashmap };
699
- }
700
- this.contentLoader.next(false);
701
- }
702
- }
703
- checkCompletedLeafnodes(leafNodes, completedCount) {
704
- if (completedCount.length > 0) {
705
- completedCount.forEach((ele) => {
706
- if (!leafNodes.includes(ele.contentId)) {
707
- leafNodes.push(ele.contentId);
708
- }
709
- });
710
- }
711
- }
712
- // async getProgressForChildCourse(request: any, content: any) {
713
- // const data: any = await this.fetchContentHistoryV2(request).toPromise().catch(_error => {})
714
- // if (data.result && data.result.contentList.length > 0) {
715
- // this.mapCompletionPercentage(content, data.result.contentList)
716
- // }
717
- // }
718
- findEnrolmentByCollectionId(enrolmentList, identifier) {
719
- return enrolmentList && enrolmentList?.length && enrolmentList.find((el) => el?.collectionId === identifier);
720
- }
721
- async mapCompletionChildPercentageProgram(course) {
722
- if (course && course.children) {
723
- await course.children.map(async (courseChild) => {
724
- if ((courseChild && courseChild.children) || courseChild.primaryCategory === NsContent.EPrimaryCategory.MODULE) {
725
- this.mapCompletionChildPercentageProgram(courseChild);
726
- course['moduleCount'] = course['moduleCount'] ? course['moduleCount'] + 1 : 1;
727
- }
728
- else {
729
- courseChild['completionPercentage'] = 100;
730
- courseChild['completionStatus'] = 2;
731
- }
732
- });
733
- }
734
- }
735
- mapModuleDurationAndProgress(content, parent) {
736
- if (content && content.children) {
737
- if (content.primaryCategory === NsContent.EPrimaryCategory.MODULE) {
738
- // content.children.map((item: NsContent.IContent)=> {
739
- /* tslint:disable-next-line */
740
- content = this.getCalculationsFromChildren(content);
741
- // })
742
- }
743
- content.children.map((item) => {
744
- // if (item.primaryCategory === NsContent.EPrimaryCategory.MODULE) {
745
- // this.mapModuleDurationAndProgress(item, parent)
746
- // } else {
747
- // this.mapModuleDurationAndProgress(item, parent)
748
- // }
749
- if (item && item.children) {
750
- this.mapModuleDurationAndProgress(item, parent);
751
- }
752
- });
753
- }
754
- }
755
- createHirarchyProgressHashmap(hierarchyData, rootCourseCategory) {
756
- if (hierarchyData && hierarchyData.children) {
757
- hierarchyData.children.forEach((child) => {
758
- if (child && child.children) {
759
- this.createHirarchyProgressHashmap(child, rootCourseCategory);
760
- }
761
- const primaryCat = child.primaryCategory;
762
- const courseCat = (child.courseCategory || child.primaryCategory || '');
763
- const isMilestone = primaryCat === 'Milestone' || courseCat === 'Milestone';
764
- const isCollection = child.mimeType === NsContent.EMimeTypes.COLLECTION;
765
- const isModule = child.primaryCategory === NsContent.EPrimaryCategory.MODULE;
766
- const isResource = child.primaryCategory === NsContent.EPrimaryCategory.RESOURCE ||
767
- child.primaryCategory === NsContent.EPrimaryCategory.PRACTICE_RESOURCE ||
768
- child.primaryCategory === NsContent.EPrimaryCategory.FINAL_ASSESSMENT ||
769
- child.primaryCategory === NsContent.EPrimaryCategory.COMP_ASSESSMENT;
770
- const isLearningPathway = rootCourseCategory === 'Learning Pathway';
771
- // Check if content is mandatory (isMandatory flag or mandatory property)
772
- const isMandatory = child.isMandatory === true || child.mandatory === true;
773
- let localMap = {
774
- parent: child?.parent,
775
- identifier: child.identifier,
776
- leafNodesCount: child.leafNodesCount || null,
777
- leafNodes: child.leafNodes || [],
778
- completionPercentage: child.completionPercentage || child.progress || 0,
779
- completionStatus: child.completionStatus || child.status || 0,
780
- status: child.status || child.completionStatus || 0,
781
- progress: child.progress,
782
- primaryCategory: child.primaryCategory,
783
- courseCategory: courseCat,
784
- duration: child.duration || 0,
785
- expectedDuration: child.expectedDuration || 0,
786
- // Additional metadata for performance optimization
787
- mimeType: child.mimeType,
788
- isLocked: child.isLocked || false,
789
- artifactUrl: child.artifactUrl || null,
790
- name: child.name || '',
791
- contentType: child.contentType || '',
792
- // Pre-computed flags for Learning Pathway
793
- isMilestone: isMilestone,
794
- isCollection: isCollection,
795
- isModule: isModule,
796
- isResource: isResource,
797
- isLearningPathway: isLearningPathway,
798
- isMandatory: isMandatory,
799
- // Milestone specific data
800
- milestoneIndex: child.milestoneIndex,
801
- completedLeafNodesCount: child.completedLeafNodesCount || 0,
802
- // Pre-assessment flag (for milestone gating)
803
- isPreAssessment: child.isPreAssessment || false,
804
- };
805
- // Debug logging for milestones
806
- if (isMilestone) {
807
- // Progress tracked for milestone
808
- }
809
- this.hashmap[child.identifier] = localMap;
810
- });
811
- }
812
- }
813
- createPreAssessmentHirarchyProgressHashmap(hierarchyData) {
814
- if (hierarchyData && hierarchyData.preEnrolmentResources) {
815
- hierarchyData.preEnrolmentResources.forEach((child) => {
816
- if (child && child.preEnrolmentResources) {
817
- this.createPreAssessmentHirarchyProgressHashmap(child);
818
- }
819
- let localMap = {};
820
- localMap = {
821
- parent: child?.parent,
822
- identifier: child.identifier,
823
- leafNodesCount: child.leafNodesCount || null,
824
- leafNodes: child.leafNodes || [],
825
- completionPercentage: child.completionPercentage || child.progress,
826
- completionStatus: child.completionStatus,
827
- status: child.status || child.completionStatus || 0,
828
- progress: child.progress,
829
- primaryCategory: child.primaryCategory,
830
- courseCategory: child.courseCategory || child.primaryCategory || '',
831
- duration: child.duration || 0,
832
- expectedDuration: child.expectedDuration || 0,
833
- // Mark as pre-assessment ONLY if explicitly set - do NOT default to true
834
- isPreAssessment: child.isPreAssessment || false,
835
- };
836
- this.hashmap[child.identifier] = localMap;
837
- });
838
- }
839
- }
840
- callHirarchyProgressHashmap(hierarchyData) {
841
- if (hierarchyData) {
842
- const rootCourseCategory = hierarchyData.courseCategory || hierarchyData.primaryCategory || '';
843
- const isLearningPathway = rootCourseCategory === 'Learning Pathway';
844
- this.hashmap[hierarchyData.identifier] = {
845
- parent: hierarchyData.parent,
846
- identifier: hierarchyData.identifier,
847
- leafNodesCount: hierarchyData.leafNodesCount || null,
848
- leafNodes: hierarchyData.leafNodes || [],
849
- completionPercentage: hierarchyData.completionPercentage || hierarchyData.progress || 0,
850
- completionStatus: hierarchyData.completionStatus || 0,
851
- progress: hierarchyData.progress,
852
- primaryCategory: hierarchyData.primaryCategory,
853
- courseCategory: rootCourseCategory,
854
- expectedDuration: hierarchyData.expectedDuration || 0,
855
- // Additional metadata
856
- mimeType: hierarchyData.mimeType,
857
- isLocked: hierarchyData.isLocked || false,
858
- artifactUrl: hierarchyData.artifactUrl || null,
859
- name: hierarchyData.name || '',
860
- contentType: hierarchyData.contentType || '',
861
- isMilestone: false,
862
- isCollection: hierarchyData.mimeType === NsContent.EMimeTypes.COLLECTION,
863
- isModule: hierarchyData.primaryCategory === NsContent.EPrimaryCategory.MODULE,
864
- isResource: false,
865
- isLearningPathway: isLearningPathway,
866
- };
867
- if (hierarchyData.primaryCategory === NsContent.EPrimaryCategory.CURATED_PROGRAM &&
868
- hierarchyData.compatibilityLevel >= 5 && hierarchyData.contextLockingType &&
869
- hierarchyData.contextLockingType === NsContent.EContextLockingType.COURSE_ASSESSMENT_ONLY) {
870
- this.hashmap[hierarchyData.identifier] = {
871
- ...this.hashmap[hierarchyData.identifier],
872
- contextLockingType: hierarchyData.contextLockingType,
873
- compatibilityLevel: hierarchyData.compatibilityLevel,
874
- };
875
- }
876
- this.createHirarchyProgressHashmap(hierarchyData, rootCourseCategory);
877
- // NOTE: computeMilestoneLockingStatus is called AFTER progress data is populated
878
- // in mapCompletionPercentageProgram, not here where completion data is still 0
879
- this.hashmap = { ...this.hashmap };
880
- }
881
- }
882
- /**
883
- * Pre-compute milestone locking status for all milestones in Learning Pathway
884
- * This avoids expensive calculations in component getters
885
- *
886
- * Locking Rules:
887
- * 0. If user is not enrolled, ALL milestones are locked
888
- * 1. All milestones are locked by default
889
- * 2. Milestone 1 (M1) unlocks when pre-assessment is completed
890
- * 3. Milestone N (N > 1) unlocks when:
891
- * - All mandatory learning items in Milestone N-1 are completed
892
- * - The assessment of Milestone N-1 is completed
893
- */
894
- computeMilestoneLockingStatus(isEnrolled = true) {
895
- if (!this.hashmap || Object.keys(this.hashmap).length === 0) {
896
- return;
897
- }
898
- console.log('=== computeMilestoneLockingStatus ===');
899
- console.log('User enrolled:', isEnrolled);
900
- // Capture initial state to detect changes
901
- const initialHashmapSnapshot = JSON.stringify(this.hashmap);
902
- // Get all milestone entries from hashmap sorted by their index or number
903
- const milestoneEntries = Object.keys(this.hashmap)
904
- .filter(key => {
905
- const item = this.hashmap[key];
906
- return item.isMilestone || item.primaryCategory === 'Milestone' || item.courseCategory === 'Milestone';
907
- })
908
- .sort((a, b) => {
909
- // Sort by milestoneIndex if available, otherwise by number in ID
910
- const itemA = this.hashmap[a];
911
- const itemB = this.hashmap[b];
912
- if (itemA.milestoneIndex !== undefined && itemB.milestoneIndex !== undefined) {
913
- return itemA.milestoneIndex - itemB.milestoneIndex;
914
- }
915
- const numA = parseInt(a.replace(/\D/g, '')) || 0;
916
- const numB = parseInt(b.replace(/\D/g, '')) || 0;
917
- return numA - numB;
918
- });
919
- // If user is NOT enrolled, lock ALL milestones
920
- if (!isEnrolled) {
921
- console.log('User not enrolled - locking ALL milestones');
922
- milestoneEntries.forEach(milestoneId => {
923
- this.hashmap[milestoneId].computedIsLocked = true;
924
- });
925
- // Also lock all children
926
- Object.keys(this.hashmap).forEach(key => {
927
- const item = this.hashmap[key];
928
- if (!item.isMilestone) {
929
- this.hashmap[key].isParentMilestoneLocked = true;
930
- }
931
- });
932
- this.hashmap = { ...this.hashmap };
933
- this.hashmapUpdated.next({ timestamp: Date.now(), hashmap: this.hashmap });
934
- return;
935
- }
936
- // Check if pre-assessment is completed (required to unlock M1)
937
- const isPreAssessmentCompleted = this.checkPreAssessmentCompletion();
938
- milestoneEntries.forEach((milestoneId, index) => {
939
- const milestone = this.hashmap[milestoneId];
940
- if (!milestone)
941
- return;
942
- // First milestone (M1) - unlocks when pre-assessment is completed
943
- if (index === 0) {
944
- this.hashmap[milestoneId].computedIsLocked = !isPreAssessmentCompleted;
945
- return;
946
- }
947
- // For subsequent milestones (M2, M3, etc.), check if previous milestone is fully completed
948
- const previousMilestoneId = milestoneEntries[index - 1];
949
- const previousMilestone = this.hashmap[previousMilestoneId];
950
- if (previousMilestone) {
951
- // SIMPLIFIED APPROACH: Check if previous milestone is 100% complete
952
- // This uses the aggregated completion percentage which is already calculated
953
- // Use Number() to ensure proper numeric comparison
954
- const prevCompletionPct = Number(previousMilestone.completionPercentage) || 0;
955
- const prevCompletionStatus = Number(previousMilestone.completionStatus) || 0;
956
- const prevStatus = Number(previousMilestone.status) || 0;
957
- const prevCompletedLeafNodes = Number(previousMilestone.completedLeafNodesCount) || 0;
958
- const prevLeafNodesCount = Number(previousMilestone.leafNodesCount) || 0;
959
- const previousMilestoneComplete = prevCompletionPct >= 100 ||
960
- prevCompletionStatus === 2 ||
961
- prevStatus === 2 ||
962
- (prevLeafNodesCount > 0 && prevCompletedLeafNodes >= prevLeafNodesCount);
963
- // If simple check doesn't show complete, fall back to detailed check
964
- let canUnlock = previousMilestoneComplete;
965
- if (!canUnlock) {
966
- // Fallback: Check individual items
967
- const isPreviousMilestoneAssessmentComplete = this.checkMilestoneAssessmentComplete(previousMilestoneId);
968
- const isPreviousMilestoneMandatoryComplete = this.checkMilestoneMandatoryContentComplete(previousMilestoneId);
969
- canUnlock = isPreviousMilestoneAssessmentComplete && isPreviousMilestoneMandatoryComplete;
970
- }
971
- this.hashmap[milestoneId].computedIsLocked = !canUnlock;
972
- }
973
- else {
974
- this.hashmap[milestoneId].computedIsLocked = true;
975
- }
976
- });
977
- // Now compute parent milestone lock status for all children
978
- Object.keys(this.hashmap).forEach(key => {
979
- const item = this.hashmap[key];
980
- if (item.isMilestone)
981
- return; // Skip milestones themselves
982
- // Traverse up to find if any ancestor milestone is locked
983
- let currentParentId = item.parent;
984
- let depth = 0;
985
- const maxDepth = 5;
986
- while (currentParentId && depth < maxDepth) {
987
- const parentData = this.hashmap[currentParentId];
988
- if (parentData) {
989
- if (parentData.isMilestone && parentData.computedIsLocked) {
990
- this.hashmap[key].isParentMilestoneLocked = true;
991
- break;
992
- }
993
- currentParentId = parentData.parent;
994
- }
995
- else {
996
- break;
997
- }
998
- depth++;
999
- }
1000
- if (!this.hashmap[key].isParentMilestoneLocked) {
1001
- this.hashmap[key].isParentMilestoneLocked = false;
1002
- }
1003
- });
1004
- // Create new hashmap reference to trigger Angular change detection
1005
- this.hashmap = { ...this.hashmap };
1006
- // Emit update event if hashmap changed (milestone lock status updated)
1007
- const finalHashmapSnapshot = JSON.stringify(this.hashmap);
1008
- if (initialHashmapSnapshot !== finalHashmapSnapshot) {
1009
- this.hashmapUpdated.next({ timestamp: Date.now(), hashmap: this.hashmap });
1010
- }
1011
- }
1012
- /**
1013
- * Trigger milestone lock update when hashmap progress is updated externally
1014
- * Called from viewer-util.service.ts after progress updates
1015
- */
1016
- triggerMilestoneLockUpdate() {
1017
- // Check if we have a Learning Pathway in the hashmap
1018
- const hasLearningPathway = Object.keys(this.hashmap).some(key => {
1019
- const item = this.hashmap[key];
1020
- return item.isLearningPathway && item.courseCategory === 'Learning Pathway';
1021
- });
1022
- if (hasLearningPathway) {
1023
- console.log('🔄 Triggering milestone lock recomputation after progress update');
1024
- // Assume enrolled since progress was just updated
1025
- this.computeMilestoneLockingStatus(true);
1026
- }
1027
- }
1028
- /**
1029
- * Check if pre-assessment (preliminary assessment) is completed
1030
- * Pre-assessment is typically a Course Assessment at the root level of Learning Pathway (before milestones)
1031
- */
1032
- checkPreAssessmentCompletion() {
1033
- // Find the Learning Pathway root
1034
- let learningPathwayId = null;
1035
- for (const key of Object.keys(this.hashmap)) {
1036
- const item = this.hashmap[key];
1037
- if (item.isLearningPathway && item.courseCategory === 'Learning Pathway') {
1038
- learningPathwayId = key;
1039
- break;
1040
- }
1041
- }
1042
- console.log('Checking pre-assessment completion. Learning Pathway ID:', learningPathwayId);
1043
- // PRIORITY 1: Look for items explicitly marked as pre-assessment
1044
- for (const key of Object.keys(this.hashmap)) {
1045
- const item = this.hashmap[key];
1046
- if (item.isPreAssessment === true) {
1047
- // Must check for actual completion - not just any value
1048
- const isCompleted = (item.completionStatus === 2 || item.status === 2 ||
1049
- (item.completionPercentage !== undefined && item.completionPercentage >= 100) ||
1050
- (item.progress !== undefined && item.progress >= 100));
1051
- console.log(`✅ Pre-assessment found (isPreAssessment flag): ${key}`, {
1052
- name: item.name,
1053
- completionStatus: item.completionStatus,
1054
- status: item.status,
1055
- completionPercentage: item.completionPercentage,
1056
- progress: item.progress,
1057
- isCompleted,
1058
- // Show ALL fields to debug what's available
1059
- allData: JSON.stringify(item, null, 2)
1060
- });
1061
- // Pre-assessment exists - return its completion status (true/false)
1062
- return isCompleted;
1063
- }
1064
- }
1065
- // PRIORITY 2: Find pre-assessment in hashmap - direct child of Learning Pathway that is NOT a milestone
1066
- // Check for first non-milestone child of Learning Pathway
1067
- for (const key of Object.keys(this.hashmap)) {
1068
- const item = this.hashmap[key];
1069
- // Check if this is a direct child of the Learning Pathway
1070
- if (item.parent !== learningPathwayId)
1071
- continue;
1072
- // Skip milestones
1073
- if (item.isMilestone)
1074
- continue;
1075
- // This is a non-milestone direct child - it's the pre-assessment
1076
- // Must check for actual completion - not just any value
1077
- const isCompleted = (item.completionStatus === 2 || item.status === 2 ||
1078
- (item.completionPercentage !== undefined && item.completionPercentage >= 100) ||
1079
- (item.progress !== undefined && item.progress >= 100));
1080
- console.log(`✅ Pre-assessment found (first non-milestone child): ${key}`, {
1081
- name: item.name,
1082
- completionStatus: item.completionStatus,
1083
- status: item.status,
1084
- completionPercentage: item.completionPercentage,
1085
- progress: item.progress,
1086
- isCompleted,
1087
- // Show ALL fields to debug what's available
1088
- allData: JSON.stringify(item, null, 2)
1089
- });
1090
- // Pre-assessment exists - return its completion status (true/false)
1091
- return isCompleted;
1092
- }
1093
- // CRITICAL: If we reach here, no pre-assessment was found in the hashmap
1094
- // This could mean either:
1095
- // 1. There IS no pre-assessment (unlock M1 by default)
1096
- // 2. The hashmap hasn't been populated yet (should lock M1 until data is ready)
1097
- // To be safe, check if ANY children exist at all
1098
- const hasAnyChildren = Object.keys(this.hashmap).some(key => this.hashmap[key].parent === learningPathwayId);
1099
- if (!hasAnyChildren) {
1100
- // Hashmap not populated yet - lock M1 until data is ready
1101
- console.log('⚠️ No children found in hashmap yet - locking M1 until data is ready');
1102
- return false;
1103
- }
1104
- // Hashmap is populated but no pre-assessment found - allow M1 to unlock
1105
- console.log('No pre-assessment found in fully populated hashmap - allowing M1 to be unlocked by default');
1106
- return true;
1107
- }
1108
- /**
1109
- * Check if a milestone's assessment is completed
1110
- * Searches for any assessment type (Course Assessment, Final Assessment, etc.) that belongs to this milestone
1111
- */
1112
- checkMilestoneAssessmentComplete(milestoneId) {
1113
- const milestone = this.hashmap[milestoneId];
1114
- // Check all items in hashmap that are assessments and belong to this milestone
1115
- for (const key of Object.keys(this.hashmap)) {
1116
- const item = this.hashmap[key];
1117
- // Check if this is an assessment type
1118
- const isAssessmentType = item.primaryCategory === 'Course Assessment' ||
1119
- item.primaryCategory === 'Final Assessment' ||
1120
- item.primaryCategory === 'Practice Question Set' ||
1121
- item.courseCategory === 'Course Assessment' ||
1122
- item.courseCategory === 'Final Assessment' ||
1123
- (item.name && item.name.toLowerCase().includes('assessment'));
1124
- if (!isAssessmentType)
1125
- continue;
1126
- // Check if this assessment belongs to this milestone
1127
- if (this.isChildOfMilestone(key, milestoneId)) {
1128
- const isCompleted = item.completionStatus === 2 || item.status === 2 || item.completionPercentage >= 100 || item.progress >= 100;
1129
- if (isCompleted) {
1130
- return true;
1131
- }
1132
- }
1133
- }
1134
- // If no assessment found, consider it as completed (no assessment requirement)
1135
- return true;
1136
- }
1137
- /**
1138
- * Check if a milestone's mandatory content is completed
1139
- * Only checks courses/content that are marked as isMandatory
1140
- */
1141
- checkMilestoneMandatoryContentComplete(milestoneId) {
1142
- const milestone = this.hashmap[milestoneId];
1143
- let mandatoryCount = 0;
1144
- let completedMandatoryCount = 0;
1145
- // Check all items in hashmap that are direct children of this milestone (courses)
1146
- for (const key of Object.keys(this.hashmap)) {
1147
- const item = this.hashmap[key];
1148
- // Check if this item is a direct child of the milestone (course level)
1149
- if (item.parent !== milestoneId)
1150
- continue;
1151
- // Skip if not a course or collection
1152
- if (item.primaryCategory !== 'Course' && !item.isCollection)
1153
- continue;
1154
- // Skip assessments - they're checked separately
1155
- const isAssessment = item.primaryCategory === 'Course Assessment' ||
1156
- item.primaryCategory === 'Final Assessment' ||
1157
- item.courseCategory === 'Course Assessment' ||
1158
- (item.name && item.name.toLowerCase().includes('assessment'));
1159
- if (isAssessment)
1160
- continue;
1161
- // Check if this content is mandatory
1162
- if (item.isMandatory) {
1163
- mandatoryCount++;
1164
- const isCompleted = item.completionStatus === 2 || item.status === 2 || item.completionPercentage >= 100 || item.progress >= 100;
1165
- if (isCompleted) {
1166
- completedMandatoryCount++;
1167
- }
1168
- }
1169
- }
1170
- const allComplete = mandatoryCount === 0 || completedMandatoryCount >= mandatoryCount;
1171
- return allComplete;
1172
- }
1173
- /**
1174
- * Check if a content item is a child (direct or nested) of a milestone
1175
- */
1176
- isChildOfMilestone(contentId, milestoneId) {
1177
- let currentId = contentId;
1178
- let depth = 0;
1179
- const maxDepth = 10;
1180
- while (currentId && depth < maxDepth) {
1181
- const item = this.hashmap[currentId];
1182
- if (!item)
1183
- return false;
1184
- if (item.parent === milestoneId)
1185
- return true;
1186
- currentId = item.parent;
1187
- depth++;
1188
- }
1189
- return false;
1190
- }
1191
- getCalculationsFromChildren(item) {
1192
- item['duration'] = item.children.reduce((sum, child) => {
1193
- return sum + Number(child.duration || 0);
1194
- }, 0);
1195
- const completedItems = _.filter(item.children, r => r.completionStatus === 2 || r.completionPercentage === 100);
1196
- const totalCount = _.toInteger(_.get(item, 'leafNodesCount')) || 1;
1197
- item['completionPercentage'] = Number(((completedItems.length / totalCount) * 100).toFixed());
1198
- item['completionStatus'] = (item.completionPercentage >= 100) ? 2 : 1;
1199
- return item;
1200
- }
1201
- fetchContentHistoryV2(req) {
1202
- req.request.fields = ['progressdetails'];
1203
- if (req.request.courseId) {
1204
- const reslut = this.http.post(`${API_END_POINTS.CONTENT_HISTORYV2}/${req.request.courseId}`, req);
1205
- // data.subscribe((subscribeData: any) => {
1206
- // this.programChildCourseResumeData.next({ resumeData: subscribeData.result.contentList, courseId: req.request.courseId })
1207
- // })
1208
- return reslut;
1209
- }
1210
- return of();
1211
- }
1212
- dowonloadCertificate(certId) {
1213
- return this.http.get(API_END_POINTS.CERT_DOWNLOAD(certId));
1214
- }
1215
- getServerDate() {
1216
- return this.http.get(API_END_POINTS.SERVER_DATE);
1217
- }
1218
- getFormById(formId) {
1219
- return this.http.get(API_END_POINTS.GET_FORM_BYID(formId));
1220
- }
1221
- submitForm(formData) {
1222
- return this.http.post(API_END_POINTS.SUBMIT_FORM, formData);
1223
- }
1224
- getFormByIdPublic(formId) {
1225
- return this.http.get(API_END_POINTS.GET_FORM_BYID_PUBLIC(formId));
1226
- }
1227
- submitFormPublic(formData) {
1228
- return this.http.post(API_END_POINTS.SUBMIT_FORM_PUBLIC, formData);
1229
- }
1230
- getApllicationsById(formId, contextId) {
1231
- return this.http.get(API_END_POINTS.GET_APPLICATIONS_BY_ID(formId, contextId));
1232
- }
1233
- shareContent(reqBody) {
1234
- return this.http.post(`${API_END_POINTS.SHARE_CONTENT}`, reqBody);
1235
- }
1236
- checkModuleWiseData(content) {
1237
- if (content && content.children) {
1238
- content.children.forEach((ele) => {
1239
- if (ele.primaryCategory === NsContent.EPrimaryCategory.MODULE) {
1240
- let moduleResourseCount = 0;
1241
- let offlineResourseCount = 0;
1242
- ele.children.forEach((childEle) => {
1243
- if (childEle.primaryCategory !== NsContent.EPrimaryCategory.OFFLINE_SESSION) {
1244
- moduleResourseCount = moduleResourseCount + 1;
1245
- }
1246
- else {
1247
- offlineResourseCount = offlineResourseCount + 1;
1248
- }
1249
- });
1250
- ele['moduleResourseCount'] = moduleResourseCount;
1251
- ele['offlineResourseCount'] = offlineResourseCount;
1252
- }
1253
- else {
1254
- if (ele.primaryCategory === NsContent.EPrimaryCategory.COURSE) {
1255
- this.checkModuleWiseData(ele);
1256
- }
1257
- }
1258
- });
1259
- }
1260
- }
1261
- async fetchCourseHeirarchy(contentData) {
1262
- if (contentData && contentData.children) {
1263
- for (const ele of contentData.children) {
1264
- if (ele.primaryCategory === NsContent.ECourseCategory.COURSE) {
1265
- await this.widgetSvc.fetchContent(ele.identifier).toPromise().then(async (subEle) => {
1266
- if (subEle.result && subEle.result.content
1267
- && subEle.result.content.children && subEle.result.content.children.length) {
1268
- ele['children'] = subEle.result.content.children;
1269
- }
1270
- });
1271
- }
1272
- }
1273
- }
1274
- }
1275
- setTranscriptionData(data) {
1276
- // console.log('data--', data)
1277
- this.transriptionDataSubject.next(data);
1278
- }
1279
- setActiveSubtitleLanguage(activeLang) {
1280
- this.transriptionActiveLanguageDataObject.next(activeLang);
1281
- }
1282
- aiGetResourceVttFile(resourceID) {
1283
- return this.http.get(`${API_END_POINTS.AI_RESOURCE_VTT_FILE}?resource_id=${resourceID}`);
1284
- }
1285
- readPreEnrollmentResourcesState(req) {
1286
- return this.http
1287
- .post(`${API_END_POINTS.PRE_ENROLLMENT_STATE_READ}`, req);
1288
- }
1289
- createContentV2(requestBody) {
1290
- return this.http
1291
- .post(`${API_END_POINTS.CREATE_RESOURCE}`, requestBody)
1292
- .pipe(map((data) => {
1293
- return data.result.identifier;
1294
- }));
1295
- }
1296
- uploadAssignmentAnswer(contentId, batchId, assignmentId, file) {
1297
- const formData = new FormData();
1298
- formData.append('file', file, file.name);
1299
- return this.http.post(`${API_END_POINTS.UPLOAD_ASSIGNMENT}/${contentId}/${batchId}/${assignmentId}`, formData);
1300
- }
1301
- readContentV2(id) {
1302
- return this.http.get(`${API_END_POINTS.READ_RESOURCE}read/${id}?mode=edit`).pipe(map((data) => {
1303
- return data.result.content;
1304
- }));
1305
- }
1306
- upload(data, contentData, options) {
1307
- const file = data.get('content');
1308
- let fileName = file.name;
1309
- if (['channel.json'].indexOf(fileName) < 0) {
1310
- fileName = this.appendToFilename(fileName);
1311
- }
1312
- const newFormData = new FormData();
1313
- newFormData.append('data', file, fileName);
1314
- return this.http.post(`${API_END_POINTS.UPLOAD_FILE}upload/${contentData.contentId}`, newFormData, options);
1315
- }
1316
- appendToFilename(filename) {
1317
- const timeStamp = new Date().getTime();
1318
- const dotIndex = filename.lastIndexOf('.');
1319
- if (dotIndex === -1) {
1320
- return filename + timeStamp;
1321
- }
1322
- return filename.substring(0, dotIndex) + timeStamp + filename.substring(dotIndex);
1323
- }
1324
- updateContentWithFewFields(requestBody, identifier) {
1325
- return this.http.patch(`${API_END_POINTS.UPDATE_RESOURCE}/${identifier}`, requestBody);
1326
- }
1327
- searchAssignments(request) {
1328
- return this.http.post(API_END_POINTS.SEARCH, request);
1329
- }
1330
- submitDraftAssignment(request) {
1331
- return this.http.put(API_END_POINTS.SUBMIT_DRAFT_ASSIGNMENT, request);
1332
- }
1333
- submitAssignment(request) {
1334
- return this.http.post(API_END_POINTS.SUBMIT_ASSIGNMENT, request);
1335
- }
1336
- notifyAssignmentSubmission(payload) {
1337
- return this.http.post(API_END_POINTS.NOTIFY_ASSIGNMENT_SUBMISSION, payload);
1338
- }
1339
- getAssignmentStatus(request) {
1340
- return this.http.post(`${API_END_POINTS.ASSIGNMENT_STATUS}`, request);
1341
- }
1342
- readAssignmentFile(contentId, batchId, assignmentId, fileName) {
1343
- // Properly encode the parameters to avoid malformed request errors
1344
- const encodedParams = new URLSearchParams({
1345
- contentId: contentId || '',
1346
- batchId: batchId || '',
1347
- formId: assignmentId || '',
1348
- fileName: fileName || ''
1349
- });
1350
- return this.http.get(`${API_END_POINTS.READ_ASSIGNMENT}?${encodedParams.toString()}`, {
1351
- responseType: 'blob',
1352
- headers: {
1353
- 'Accept': 'application/octet-stream, application/pdf, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document'
1354
- }
1355
- }).pipe(catchError((error) => {
1356
- return throwError(() => error);
1357
- }));
1358
- }
1359
- /**
1360
- * Generate milestone achievement
1361
- * @param userId User ID
1362
- * @param courseId Course identifier
1363
- * @param batchId Batch ID
1364
- * @param milestoneId Milestone identifier (e.g., 'm1', 'm2')
1365
- */
1366
- generateMilestoneAchievement(userId, courseId, batchId, milestoneId) {
1367
- const apiUrl = '/apis/proxies/v8/achievement/dynamic/v1/generate';
1368
- const request = {
1369
- request: {
1370
- userId,
1371
- courseId,
1372
- batchId,
1373
- milestoneId
1374
- }
1375
- };
1376
- return this.http.post(apiUrl, request);
1377
- }
1378
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AppTocService, deps: [{ token: i1.HttpClient }, { token: i2.ContentLanguageService }, { token: i3.ConfigurationsService }, { token: i4.WidgetContentService }], target: i0.ɵɵFactoryTarget.Injectable }); }
1379
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AppTocService, providedIn: 'root' }); }
1380
- }
1381
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AppTocService, decorators: [{
1382
- type: Injectable,
1383
- args: [{
1384
- providedIn: 'root'
1385
- }]
1386
- }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: i2.ContentLanguageService }, { type: i3.ConfigurationsService }, { type: i4.WidgetContentService }]; } });
1387
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLXRvYy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vbGlicmFyeS9zdW5iaXJkLWNiL3RvYy9zcmMvbGliL3NlcnZpY2VzL2FwcC10b2Muc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFBO0FBRTFDLE9BQU8sRUFBRSxPQUFPLEVBQWMsS0FBSyxFQUFnQixlQUFlLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBRSxNQUFNLE1BQU0sQ0FBQTtBQUVoRyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sbUNBQW1DLENBQUE7QUFDN0QsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sd0NBQXdDLENBQUE7QUFFM0UsT0FBTyxFQUFFLFFBQVEsRUFBYSxNQUFNLHlCQUF5QixDQUFBO0FBRTdELDJCQUEyQjtBQUMzQixPQUFPLENBQUMsTUFBTSxRQUFRLENBQUE7QUFFdEIsT0FBTyxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQTs7Ozs7O0FBRWhELHVDQUF1QztBQUN2QyxNQUFNLGlCQUFpQixHQUFHLG9CQUFvQixDQUFBO0FBQzlDLE1BQU0sYUFBYSxHQUFHLGtCQUFrQixDQUFBO0FBRXhDLE1BQU0sY0FBYyxHQUFHO0lBQ3JCLFlBQVksRUFBRSxHQUFHLGFBQWEsaUNBQWlDO0lBQy9ELGVBQWUsRUFBRSxHQUFHLGlCQUFpQixrQkFBa0I7SUFDdkQsWUFBWSxFQUFFLEdBQUcsaUJBQWlCLGVBQWU7SUFDakQsaUJBQWlCLEVBQUUsdUNBQXVDO0lBQzFELGNBQWMsRUFBRSxDQUFDLFNBQWlCLEVBQUUsRUFBRSxDQUFDLEdBQUcsaUJBQWlCLFlBQVksU0FBUyxTQUFTO0lBQ3pGLG1CQUFtQixFQUFFLENBQUMsU0FBaUIsRUFBRSxPQUFlLEVBQUUsR0FBVyxFQUFFLEVBQUUsQ0FDdkUsaURBQWlELFNBQVMs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S0FBSyxDQUFDLENBQUM7UUFDakMsQ0FBQyxDQUFDLENBQ0gsQ0FBQztJQUNKLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCw0QkFBNEIsQ0FBQyxNQUFjLEVBQUUsUUFBZ0IsRUFBRSxPQUFlLEVBQUUsV0FBbUI7UUFDakcsTUFBTSxNQUFNLEdBQUcsa0RBQWtELENBQUE7UUFDakUsTUFBTSxPQUFPLEdBQUc7WUFDZCxPQUFPLEVBQUU7Z0JBQ1AsTUFBTTtnQkFDTixRQUFRO2dCQUNSLE9BQU87Z0JBQ1AsV0FBVzthQUNaO1NBQ0YsQ0FBQTtRQUNELE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFBO0lBQ3hDLENBQUM7K0dBNytDVSxhQUFhO21IQUFiLGFBQWEsY0FGWixNQUFNOzs0RkFFUCxhQUFhO2tCQUh6QixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJ1xuaW1wb3J0IHsgRGF0YSB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcidcbmltcG9ydCB7IFN1YmplY3QsIE9ic2VydmFibGUsIEVNUFRZLCBTdWJzY3JpcHRpb24sIEJlaGF2aW9yU3ViamVjdCwgb2YsIHRocm93RXJyb3IgfSBmcm9tICdyeGpzJ1xuaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJ1xuaW1wb3J0IHsgTnNDb250ZW50IH0gZnJvbSAnLi4vX3NlcnZpY2VzL3dpZGdldC1jb250ZW50Lm1vZGVsJ1xuaW1wb3J0IHsgTnNDb250ZW50Q29uc3RhbnRzIH0gZnJvbSAnLi4vX2NvbnN0YW50cy93aWRnZXQtY29udGVudC5jb25zdGFudHMnXG5pbXBvcnQgeyBXaWRnZXRDb250ZW50U2VydmljZSB9IGZyb20gJy4uL19zZXJ2aWNlcy93aWRnZXQtY29udGVudC5zZXJ2aWNlJ1xuaW1wb3J0IHsgTnNBcHBUb2MsIE5zQ29ob3J0cyB9IGZyb20gJy4uL21vZGVscy9hcHAtdG9jLm1vZGVsJ1xuaW1wb3J0IHsgVEZldGNoU3RhdHVzLCBDb25maWd1cmF0aW9uc1NlcnZpY2UgfSBmcm9tICdAc3VuYmlyZC1jYi91dGlscy12Midcbi8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZVxuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJ1xuaW1wb3J0IHsgQ29udGVudExhbmd1YWdlU2VydmljZSB9IGZyb20gJ0BzdW5iaXJkLWNiL2NvbnN1bXB0aW9uJ1xuaW1wb3J0IHsgbWFwLCBjYXRjaEVycm9yIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnXG5cbi8vIFRPRE86IG1vdmUgdGhpcyBpbiBzb21lIGNvbW1vbiBwbGFjZVxuY29uc3QgUFJPVEVDVEVEX1NMQUdfVjggPSAnL2FwaXMvcHJvdGVjdGVkL3Y4J1xuY29uc3QgUFJPWFlfU0xBR19WOCA9ICcvYXBpcy9wcm94aWVzL3Y4J1xuXG5jb25zdCBBUElfRU5EX1BPSU5UUyA9IHtcbiAgQkFUQ0hfQ1JFQVRFOiBgJHtQUk9YWV9TTEFHX1Y4fS9sZWFybmVyL2NvdXJzZS92MS9iYXRjaC9jcmVhdGVgLFxuICBDT05URU5UX1BBUkVOVFM6IGAke1BST1RFQ1RFRF9TTEFHX1Y4fS9jb250ZW50L3BhcmVudHNgLFxuICBDT05URU5UX05FWFQ6IGAke1BST1RFQ1RFRF9TTEFHX1Y4fS9jb250ZW50L25leHRgLFxuICBDT05URU5UX0hJU1RPUllWMjogYC9hcGlzL3Byb3hpZXMvdjgvcmVhZC9jb250ZW50LXByb2dyZXNgLFxuICBDT05URU5UX1BBUkVOVDogKGNvbnRlbnRJZDogc3RyaW5nKSA9PiBgJHtQUk9URUNURURfU0xBR19WOH0vY29udGVudC8ke2NvbnRlbnRJZH0vcGFyZW50YCxcbiAgQ09OVEVOVF9BVVRIX1BBUkVOVDogKGNvbnRlbnRJZDogc3RyaW5nLCByb290T3JnOiBzdHJpbmcsIG9yZzogc3RyaW5nKSA9PlxuICAgIGAvYXBpcy9hdXRoQXBpL2FjdGlvbi9jb250ZW50L3BhcmVudC9oaWVyYXJjaHkvJHtjb250ZW50SWR9P3Jvb3RPcmc9JHtyb290T3JnfSZvcmc9JHtvcmd9YCxcbiAgQ09IT1JUUzogKGNvaG9ydFR5cGU6IE5zQ29ob3J0cy5FQ29ob3J0VHlwZXMsIGNvbnRlbnRJZDogc3RyaW5nKSA9PlxuICAgIGAke1BST1RFQ1RFRF9TTEFHX1Y4fS9jb2hvcnRzLyR7Y29ob3J0VHlwZX0vJHtjb250ZW50SWR9YCxcbiAgRVhURVJOQUxfQ09OVEVOVDogKGNvbnRlbnRJZDogc3RyaW5nKSA9PlxuICAgIGAke1BST1RFQ1RFRF9TTEFHX1Y4fS9jb250ZW50L2V4dGVybmFsLWFjY2Vzcy8ke2NvbnRlbnRJZH1gLFxuICBDT0hPUlRTX0dST1VQX1VTRVI6IChncm91cElkOiBudW1iZXIpID0+IGAke1BST1RFQ1RFRF9TTEFHX1Y4fS9jb2hvcnRzLyR7Z3JvdXBJZH1gLFxuICBSRUxBVEVEX1JFU09VUkNFOiAoY29udGVudElkOiBzdHJpbmcsIGNvbnRlbnRUeXBlOiBzdHJpbmcpID0+XG4gICAgYCR7UFJPVEVDVEVEX1NMQUdfVjh9L2todWIvZmV0Y2hSZWxhdGVkUmVzb3VyY2VzLyR7Y29udGVudElkfS8ke2NvbnRlbnRUeXBlfWAsXG4gIFBPU1RfQVNTRVNTTUVOVDogKGNvbnRlbnRJZDogc3RyaW5nKSA9PlxuICAgIGAke1BST1RFQ1RFRF9TTEFHX1Y4fS91c2VyL2V2YWx1YXRlL3Bvc3QtYXNzZXNzbWVudC8ke2NvbnRlbnRJZH1gLFxuICBHRVRfQ09OVEVOVDogKGNvbnRlbnRJZDogc3RyaW5nKSA9PlxuICAgIGAke1BST1hZX1NMQUdfVjh9L2FjdGlvbi9jb250ZW50L3YzL3JlYWQvJHtjb250ZW50SWR9YCxcbiAgQ0VSVF9ET1dOTE9BRDogKGNlcnRJZDogYW55KSA9PiBgJHtQUk9URUNURURfU0xBR19WOH0vY29ob3J0cy9jb3Vyc2UvYmF0Y2gvY2VydC9kb3dubG9hZC8ke2NlcnRJZH1gLFxuICBTRVJWRVJfREFURTogJ2FwaXMvcHVibGljL3Y4L3N5c3RlbURhdGUnLFxuICBTSEFSRV9DT05URU5UOiAnL2FwaXMvcHJveGllcy92OC91c2VyL3YxL2NvbnRlbnQvcmVjb21tZW5kJyxcbiAgR0VUX0ZPUk1fQllJRDogKGZvcm1JZDogc3RyaW5nKSA9PiBgYXBpcy9wcm94aWVzL3Y4L2Zvcm1zL3YyL2dldEZvcm1CeUlkP2Zvcm1JZD0ke2Zvcm1JZH1gLFxuICAvLyBTVUJNSVRfRk9STTogYC9hcGlzL3Byb3hpZXMvdjgvZm9ybXMvdjEvc2F2ZUZvcm1TdWJtaXRgLFxuICBTVUJNSVRfRk9STTogYGFwaXMvcHJveGllcy92OC9mb3Jtcy92Mi9zYXZlRm9ybVN1Ym1pdGAsXG4gIEdFVF9GT1JNX0JZSURfUFVCTElDOiAoZm9ybUlkOiBzdHJpbmcpID0+IGBhcGlzL3B1YmxpYy92OC9wdWJsaWMvZm9ybXMvdjIvZ2V0Rm9ybUJ5SWQ/Zm9ybUlkPSR7Zm9ybUlkfWAsXG4gIFNVQk1JVF9GT1JNX1BVQkxJQzogYGFwaXMvcHVibGljL3Y4L3B1YmxpYy9mb3Jtcy92Mi9zYXZlRm9ybVN1Ym1pdGAsXG4gIC8vIGdldCBhbnN3ZXJzIGZvciBmb3JtXG4gIEdFVF9BUFBMSUNBVElPTlNfQllfSUQ6IChmb3JtSWQ6IHN0cmluZywgY29udGV4dElkOiBzdHJpbmcpID0+IGAvYXBpcy9wcm94aWVzL3Y4L2Zvcm1zL3YyL2dldEFwcGxpY2F0aW9uc0J5SWQ/Zm9ybUlkPSR7Zm9ybUlkfSZjb250ZXh0SWQ9JHtjb250ZXh0SWR9YCxcbiAgQUlfUkVTT1VSQ0VfVlRUX0ZJTEU6IGAke1BST1hZX1NMQUdfVjh9L2NoYXRib3QvdjMvdHJhbnNjb2Rlci9zdGF0c2AsXG4gIC8vIEdFVF9GT1JNX0JZSUQ6IChmb3JtSWQ6IHN0cmluZykgPT4gYGFwaXMvcHJveGllcy92OC9mb3Jtcy9nZXRGb3JtQnlJZD9pZD0ke2Zvcm1JZH1gLFxuICBQUkVfRU5ST0xMTUVOVF9TVEFURV9SRUFEOiBgL2FwaXMvcHJveGllcy92OC9jb250ZW50L3YyL3N0YXRlL3JlYWRgLFxuICBDUkVBVEVfUkVTT1VSQ0U6IGBhcGlzL3Byb3hpZXMvdjgvYWN0aW9uL2NvbnRlbnQvdjMvY3JlYXRlYCxcbiAgUkVBRF9SRVNPVVJDRTogYGFwaXMvcHJveGllcy92OC9hY3Rpb24vY29udGVudC92My9gLFxuICBVUExPQURfRklMRTogYGFwaXMvcHJveGllcy92OC91cGxvYWQvYWN0aW9uL2NvbnRlbnQvdjMvYCxcbiAgVVBEQVRFX1JFU09VUkNFOiBgYXBpcy9wcm94aWVzL3Y4L2FjdGlvbi9jb250ZW50L3YzL3VwZGF0ZWAsXG4gIFNFQVJDSDogYGFwaXMvcHJveGllcy92OC9hc3NpZ25tZW50L3YxL3NlYXJjaGAsXG4gIFNVQk1JVF9EUkFGVF9BU1NJR05NRU5UOiBgYXBpcy9wcm94aWVzL3Y4L2Fzc2lnbm1lbnQvdjEvc3VibWl0RHJhZnRgLFxuICBTVUJNSVRfQVNTSUdOTUVOVDogYGFwaXMvcHJveGllcy92OC9hc3NpZ25tZW50L3YxL3N1Ym1pdGAsXG4gIEFTU0lHTk1FTlRfU1RBVFVTOiBgYXBpcy9wcm94aWVzL3Y4L2Zvcm1zL3YyL3N1Ym1pc3Npb25zL3NlYXJjaGAsXG4gIFVQTE9BRF9BU1NJR05NRU5UOiBgYXBpcy9wcm94aWVzL3Y4L3N0b3JhZ2UvdjEvYnAvYXNzaWdubWVudC9hbnN3ZXJgLFxuICBSRUFEX0FTU0lHTk1FTlQ6IGBhcGlzL3Byb3hpZXMvdjgvc3RvcmFnZS92MS9icC9hc3NpZ25tZW50L2Fuc3dlci9yZWFkL2ZpbGVgLFxuICBOT1RJRllfQVNTSUdOTUVOVF9TVUJNSVNTSU9OOiBgYXBpcy9wcm94aWVzL3Y4L3YxL25vdGlmeUFzc2lnbm1lbnQvc3VibWl0YCxcbn1cblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgQXBwVG9jU2VydmljZSB7XG4gIGFuYWx5dGljc1JlcGxheVN1YmplY3Q6IFN1YmplY3Q8YW55PiA9IG5ldyBTdWJqZWN0KClcbiAgYW5hbHl0aWNzRmV0Y2hTdGF0dXM6IFRGZXRjaFN0YXR1cyA9ICdub25lJ1xuICBiYXRjaFJlcGxheVN1YmplY3Q6IFN1YmplY3Q8YW55PiA9IG5ldyBTdWJqZWN0KClcbiAgc2V0QmF0Y2hEYXRhU3ViamVjdDogU3ViamVjdDxhbnk+ID0gbmV3IFN1YmplY3QoKVxuICBnZXRTZWxlY3RlZEJhdGNoOiBTdWJqZWN0PGFueT4gPSBuZXcgU3ViamVjdCgpXG4gIHNldFdGRGF0YVN1YmplY3Q6IFN1YmplY3Q8YW55PiA9IG5ldyBTdWJqZWN0KClcbiAgcmVzdW1lRGF0YTogU3ViamVjdDxOc0NvbnRlbnQuSUNvbnRpbnVlTGVhcm5pbmdEYXRhIHwgbnVsbD4gPSBuZXcgU3ViamVjdDxhbnk+KClcbiAgcHJpdmF0ZSBzaG93U3VidGl0bGVPbkJhbm5lcnMgPSBmYWxzZVxuICBwcml2YXRlIGNhblNob3dEZXNjcmlwdGlvbiA9IGZhbHNlXG4gIHJlc3VtZURhdGFTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbiB8IG51bGwgPSBudWxsXG4gIHByaW1hcnlDYXRlZ29yeSA9IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5XG4gIHByaXZhdGUgdXBkYXRlUmV2aWV3cyA9IG5ldyBCZWhhdmlvclN1YmplY3QoZmFsc2UpXG4gIHVwZGF0ZVJldmlld3NPYnNlcnZhYmxlID0gdGhpcy51cGRhdGVSZXZpZXdzLmFzT2JzZXJ2YWJsZSgpXG4gIHB1YmxpYyBzZXJ2ZXJEYXRlID0gbmV3IEJlaGF2aW9yU3ViamVjdCgnJylcbiAgY3VycmVudFNlcnZlckRhdGUgPSB0aGlzLnNlcnZlckRhdGUuYXNPYnNlcnZhYmxlKClcbiAgcHVibGljIGNvbnRlbnRMb2FkZXIgPSBuZXcgQmVoYXZpb3JTdWJqZWN0KGZhbHNlKVxuICBjb250ZW50TG9hZGVyJCA9IHRoaXMuY29udGVudExvYWRlci5hc09ic2VydmFibGUoKVxuICBwdWJsaWMgZ2V0UGFnZVNjcm9sbCA9IG5ldyBCZWhhdmlvclN1YmplY3QodHJ1ZSlcbiAgdXBkYXRlUGFnZVNjcm9sbCA9IHRoaXMuZ2V0UGFnZVNjcm9sbC5hc09ic2VydmFibGUoKVxuICBwdWJsaWMgaGFzaG1hcDogYW55ID0ge31cbiAgcHJpdmF0ZSBoYXNobWFwVXBkYXRlZCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8YW55PihudWxsKVxuICBoYXNobWFwVXBkYXRlZCQgPSB0aGlzLmhhc2htYXBVcGRhdGVkLmFzT2JzZXJ2YWJsZSgpXG4gIHByaXZhdGUgdHJhbnNyaXB0aW9uRGF0YVN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGFueT4obnVsbCk7IC8vIFN0YXJ0IHdpdGggbnVsbFxuICB0cmFuc2NyaXB0aW9uRGF0YSQgPSB0aGlzLnRyYW5zcmlwdGlvbkRhdGFTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICBwdWJsaWMgdHJhbnNyaXB0aW9uQWN0aXZlTGFuZ3VhZ2VEYXRhT2JqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxhbnk+KG51bGwpO1xuICBwdWJsaWMgdHJhbnNyaXB0aW9uQWN0aXZlTGFuZ3VhZ2VEYXRhT2JqZWN0JCA9IHRoaXMudHJhbnNyaXB0aW9uQWN0aXZlTGFuZ3VhZ2VEYXRhT2JqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICBwdWJsaWMgdHJhbnNyaXB0aW9uSWRlbnRpZmllciA9IG5ldyBTdWJqZWN0KCk7IC8vIFN0YXJ0IHdpdGggbnVsbFxuICBjaGFuZ2VUcmFuc2NyaXB0aW9uTGFuZ3VhZ2VFdmVudCA9IG5ldyBTdWJqZWN0KClcbiAgcGxheVRyYW5zY3JpcHRpb25WaWRlbyA9IG5ldyBTdWJqZWN0KClcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBodHRwOiBIdHRwQ2xpZW50LCBwcml2YXRlIGNvbnRlbnRMYW5nU3ZjOiBDb250ZW50TGFuZ3VhZ2VTZXJ2aWNlLCBwcml2YXRlIGNvbmZpZ1N2YzogQ29uZmlndXJhdGlvbnNTZXJ2aWNlLCBwcml2YXRlIHdpZGdldFN2YzogV2lkZ2V0Q29udGVudFNlcnZpY2UpIHtcbiAgICAvLyB0aGlzIHJlc3VtZSBkYXRhIHN1YnNjcmlwdGlvbiBpcyBmb3Igb24gbG9hZFxuICAgIHRoaXMucmVzdW1lRGF0YVN1YnNjcmlwdGlvbiA9IHRoaXMucmVzdW1lRGF0YS5zdWJzY3JpYmUoXG4gICAgICAoX2RhdGFSZXN1bHQ6IGFueSkgPT4ge1xuICAgICAgfSlcbiAgfVxuXG4gIGdldCBzdWJ0aXRsZU9uQmFubmVycygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zaG93U3VidGl0bGVPbkJhbm5lcnNcbiAgfVxuICBzZXQgc3VidGl0bGVPbkJhbm5lcnModmFsOiBib29sZWFuKSB7XG4gICAgdGhpcy5zaG93U3VidGl0bGVPbkJhbm5lcnMgPSB2YWxcbiAgfVxuICBnZXQgc2hvd0Rlc2NyaXB0aW9uKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmNhblNob3dEZXNjcmlwdGlvblxuICB9XG4gIHNldCBzaG93RGVzY3JpcHRpb24odmFsOiBib29sZWFuKSB7XG4gICAgdGhpcy5jYW5TaG93RGVzY3JpcHRpb24gPSB2YWxcbiAgfVxuXG4gIHVwZGF0ZUJhdGNoRGF0YSgpIHtcbiAgICB0aGlzLmJhdGNoUmVwbGF5U3ViamVjdC5uZXh0KClcbiAgfVxuXG4gIHNldEJhdGNoRGF0YShkYXRhOiBOc0NvbnRlbnQuSUJhdGNoTGlzdFJlc3BvbnNlKSB7XG4gICAgdGhpcy5zZXRCYXRjaERhdGFTdWJqZWN0Lm5leHQoZGF0YSlcbiAgfVxuXG4gIHNldFdGRGF0YShkYXRhOiBhbnkpIHtcbiAgICB0aGlzLnNldFdGRGF0YVN1YmplY3QubmV4dChkYXRhKVxuICB9XG5cbiAgdXBkYXRlUmVzdW1hRGF0YShkYXRhOiBhbnkpIHtcbiAgICB0aGlzLnJlc3VtZURhdGEubmV4dChkYXRhKVxuICB9XG5cbiAgY2hhbmdlVXBkYXRlUmV2aWV3cyhzdGF0ZTogYm9vbGVhbikge1xuICAgIHRoaXMudXBkYXRlUmV2aWV3cy5uZXh0KHN0YXRlKVxuICB9XG4gIGdldFNlbGVjdGVkQmF0Y2hEYXRhKGRhdGE6IGFueSkge1xuICAgIHRoaXMuZ2V0U2VsZWN0ZWRCYXRjaC5uZXh0KGRhdGEpXG4gIH1cblxuICBjaGFuZ2VTZXJ2ZXJEYXRlKHN0YXRlOiBhbnkpIHtcbiAgICB0aGlzLnNlcnZlckRhdGUubmV4dChzdGF0ZSlcbiAgfVxuXG4gIG1hcFNlc3Npb25Db21wbGV0aW9uUGVyY2VudGFnZShiYXRjaERhdGE6IGFueSwgcmVzdW1lRGF0YVBhc3M/OiBhbnkpIHtcbiAgICBpZiAocmVzdW1lRGF0YVBhc3MgJiYgcmVzdW1lRGF0YVBhc3MubGVuZ3RoKSB7XG4gICAgICBpZiAocmVzdW1lRGF0YVBhc3MgJiYgcmVzdW1lRGF0YVBhc3MubGVuZ3RoICYmIGJhdGNoRGF0YS5jb250ZW50ICYmIGJhdGNoRGF0YS5jb250ZW50Lmxlbmd0aCkge1xuICAgICAgICB0aGlzLnNlc3Npb25Db21wbGV0aW9uUGVyY2VudGFnZShiYXRjaERhdGEsIHJlc3VtZURhdGFQYXNzKVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJlc3VtZURhdGFTdWJzY3JpcHRpb24gPSB0aGlzLnJlc3VtZURhdGEuc3Vic2NyaWJlKFxuICAgICAgICAoZGF0YVJlc3VsdDogYW55KSA9PiB7XG4gICAgICAgICAgaWYgKGRhdGFSZXN1bHQgJiYgZGF0YVJlc3VsdC5sZW5ndGggJiYgYmF0Y2hEYXRhLmNvbnRlbnQgJiYgYmF0Y2hEYXRhLmNvbnRlbnQubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLnNlc3Npb25Db21wbGV0aW9uUGVyY2VudGFnZShiYXRjaERhdGEsIGRhdGFSZXN1bHQpXG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5jb250ZW50TG9hZGVyLm5leHQoZmFsc2UpXG4gICAgICAgIH0pXG4gICAgfVxuXG4gIH1cbiAgc2Vzc2lvbkNvbXBsZXRpb25QZXJjZW50YWdlKGJhdGNoRGF0YTogYW55LCByZXN1bWVEYXRhUGFzczogYW55KSB7XG4gICAgaWYgKHJlc3VtZURhdGFQYXNzICYmIHJlc3VtZURhdGFQYXNzLmxlbmd0aCkge1xuICAgICAgaWYgKGJhdGNoRGF0YSAmJiBiYXRjaERhdGEuY29udGVudFswXSAmJlxuICAgICAgICBiYXRjaERhdGEuY29udGVudFswXS5iYXRjaEF0dHJpYnV0ZXMgJiZcbiAgICAgICAgYmF0Y2hEYXRhLmNvbnRlbnRbMF0uYmF0Y2hBdHRyaWJ1dGVzLnNlc3Npb25EZXRhaWxzX3YyXG4gICAgICApIHtcbiAgICAgICAgYmF0Y2hEYXRhLmNvbnRlbnRbMF0uYmF0Y2hBdHRyaWJ1dGVzLnNlc3Npb25EZXRhaWxzX3YyLm1hcCgoc2Q6IGFueSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGZvdW5kQ29udGVudCA9IHJlc3VtZURhdGFQYXNzLmZpbmQoKGVsOiBhbnkpID0+IGVsLmNvbnRlbnRJZCA9PT0gc2Quc2Vzc2lvbklkKVxuICAgICAgICAgIGlmIChmb3VuZENvbnRlbnQpIHtcbiAgICAgICAgICAgIHNkLmNvbXBsZXRpb25QZXJjZW50YWdlID0gZm91bmRDb250ZW50LmNvbXBsZXRpb25QZXJjZW50YWdlXG4gICAgICAgICAgICBzZC5jb21wbGV0aW9uU3RhdHVzID0gZm91bmRDb250ZW50LnN0YXR1c1xuICAgICAgICAgICAgc2QubGFzdENvbXBsZXRlZFRpbWUgPSBmb3VuZENvbnRlbnQubGFzdENvbXBsZXRlZFRpbWVcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIHRoaXMuY29udGVudExvYWRlci5uZXh0KGZhbHNlKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHNob3dTdGFydEJ1dHRvbihjb250ZW50OiBOc0NvbnRlbnQuSUNvbnRlbnQgfCBudWxsKTogeyBzaG93OiBib29sZWFuOyBtc2c6IHN0cmluZyB9IHtcbiAgICBjb25zdCBzdGF0dXMgPSB7XG4gICAgICBzaG93OiBmYWxzZSxcbiAgICAgIG1zZzogJycsXG4gICAgfVxuICAgIGlmIChjb250ZW50KSB7XG4gICAgICBpZiAoXG4gICAgICAgIGNvbnRlbnQuYXJ0aWZhY3RVcmwgJiYgY29udGVudC5hcnRpZmFjdFVybC5tYXRjaCgveW91dHUoLik/YmUvZ2kpICYmXG4gICAgICAgIHRoaXMuY29uZmlnU3ZjLnVzZXJQcm9maWxlICYmXG4gICAgICAgIHRoaXMuY29uZmlnU3ZjLnVzZXJQcm9maWxlLmNvdW50cnkgPT09ICdDaGluYSdcbiAgICAgICkge1xuICAgICAgICBzdGF0dXMuc2hvdyA9IGZhbHNlXG4gICAgICAgIHN0YXR1cy5tc2cgPSAneW91dHViZUZvcmJpZGRlbidcbiAgICAgICAgcmV0dXJuIHN0YXR1c1xuICAgICAgfVxuICAgICAgaWYgKGNvbnRlbnQucmVzb3VyY2VUeXBlICE9PSAnQ2VydGlmaWNhdGlvbicpIHtcbiAgICAgICAgc3RhdHVzLnNob3cgPSB0cnVlXG4gICAgICAgIHJldHVybiBzdGF0dXNcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHN0YXR1c1xuICB9XG5cbiAgaW5pdERhdGEoZGF0YTogRGF0YSwgbmVlZFJlc3VtZURhdGE6IGJvb2xlYW4gPSBmYWxzZSk6IE5zQXBwVG9jLklXc1RvY1Jlc3BvbnNlIHtcbiAgICBsZXQgY29udGVudDogTnNDb250ZW50LklDb250ZW50IHwgbnVsbCA9IG51bGxcbiAgICBsZXQgZXJyb3JDb2RlOiBOc0FwcFRvYy5FV3NUb2NFcnJvckNvZGUgfCBudWxsID0gbnVsbFxuICAgIHRoaXMuY29udGVudExvYWRlci5uZXh0KHRydWUpXG4gICAgaWYgKGRhdGEuY29udGVudCAmJiBkYXRhLmNvbnRlbnQuZGF0YSAmJiBkYXRhLmNvbnRlbnQuZGF0YS5pZGVudGlmaWVyKSB7XG4gICAgICBjb250ZW50ID0gZGF0YS5jb250ZW50LmRhdGFcbiAgICAgIGlmIChuZWVkUmVzdW1lRGF0YSkge1xuICAgICAgICB0aGlzLnJlc3VtZURhdGFTdWJzY3JpcHRpb24gPSB0aGlzLnJlc3VtZURhdGEuc3Vic2NyaWJlKFxuICAgICAgICAgIChkYXRhUmVzdWx0OiBhbnkpID0+IHtcbiAgICAgICAgICAgIGlmIChkYXRhUmVzdWx0ICYmIGRhdGFSZXN1bHQubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIHRoaXMuY29udGVudExvYWRlci5uZXh0KHRydWUpXG4gICAgICAgICAgICAgIHRoaXMubWFwQ29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudCwgZGF0YVJlc3VsdClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogbm8tY29uc29sZVxuICAgICAgICAgICAgY29uc29sZS5sb2coJ2Vycm9yIG9uIHJlc3VtZURhdGFTdWJzY3JpcHRpb24nKVxuICAgICAgICAgIH0sXG4gICAgICAgIClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuY29udGVudExvYWRlci5uZXh0KGZhbHNlKVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNvbnRlbnRMb2FkZXIubmV4dChmYWxzZSlcbiAgICAgIGlmIChkYXRhLmVycm9yKSB7XG4gICAgICAgIGVycm9yQ29kZSA9IE5zQXBwVG9jLkVXc1RvY0Vycm9yQ29kZS5BUElfRkFJTFVSRVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXJyb3JDb2RlID0gTnNBcHBUb2MuRVdzVG9jRXJyb3JDb2RlLk5PX0RBVEFcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gdGhpcy5jb250ZW50TG9hZGVyLm5leHQoZmFsc2UpXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQsXG4gICAgICBlcnJvckNvZGUsXG4gICAgfVxuICB9XG5cbiAgbWFwQ29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudDogTnNDb250ZW50LklDb250ZW50IHwgbnVsbCwgZGF0YVJlc3VsdDogYW55KSB7XG4gICAgaWYgKGNvbnRlbnQgJiYgY29udGVudC5jaGlsZHJlbikge1xuICAgICAgY29udGVudC5jaGlsZHJlbi5tYXAoY2hpbGQgPT4ge1xuICAgICAgICBjb25zdCBmb3VuZENvbnRlbnQgPSBkYXRhUmVzdWx0LmZpbmQoKGVsOiBhbnkpID0+IGVsLmNvbnRlbnRJZCA9PT0gY2hpbGQuaWRlbnRpZmllcilcbiAgICAgICAgaWYgKGZvdW5kQ29udGVudCkge1xuICAgICAgICAgIGNoaWxkLmNvbXBsZXRpb25QZXJjZW50YWdlID0gZm91bmRDb250ZW50LmNvbXBsZXRpb25QZXJjZW50YWdlIHx8IGZvdW5kQ29udGVudC5wcm9ncmVzc1xuICAgICAgICAgIGNoaWxkLmNvbXBsZXRpb25TdGF0dXMgPSBmb3VuZENvbnRlbnQuc3RhdHVzXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5tYXBDb21wbGV0aW9uUGVyY2VudGFnZShjaGlsZCwgZGF0YVJlc3VsdClcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICAgIHRoaXMuY29udGVudExvYWRlci5uZXh0KGZhbHNlKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNvbnRlbnRMb2FkZXIubmV4dChmYWxzZSlcbiAgICB9XG4gIH1cblxuICBtYXBNb2R1bGVDb3VudChjb250ZW50OiBOc0NvbnRlbnQuSUNvbnRlbnQpIHtcbiAgICBpZiAoY29udGVudCAmJiBjb250ZW50LmNoaWxkcmVuKSB7XG4gICAgICBjb250ZW50LmNoaWxkcmVuLm1hcChjaGlsZCA9PiB7XG4gICAgICAgIGlmIChjaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk1PRFVMRSkge1xuICAgICAgICAgIGNvbnRlbnRbJ21vZHVsZUNvdW50J10gPSBjb250ZW50Wydtb2R1bGVDb3VudCddID8gY29udGVudFsnbW9kdWxlQ291bnQnXSArIDEgOiAxXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNoaWxkLnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuQ09VUlNFKSB7XG4gICAgICAgICAgdGhpcy5tYXBNb2R1bGVDb3VudChjaGlsZClcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9XG4gIH1cblxuICBnZXRNaW1lVHlwZShjb250ZW50OiBOc0NvbnRlbnQuSUNvbnRlbnQsIGlkZW50aWZpZXI6IHN0cmluZyk6IE5zQ29udGVudC5FTWltZVR5cGVzIHtcbiAgICBpZiAoY29udGVudC5pZGVudGlmaWVyID09PSBpZGVudGlmaWVyKSB7XG4gICAgICByZXR1cm4gY29udGVudC5taW1lVHlwZVxuICAgIH1cbiAgICBpZiAoY29udGVudCAmJiBjb250ZW50LmNoaWxkcmVuKSB7XG4gICAgICBpZiAoY29udGVudC5jaGlsZHJlbi5sZW5ndGggPT09IDApIHtcbiAgICAgICAgLy8gaWYgKGNvbnRlbnQuY2hpbGRyZW5bMF0uaWRlbnRpZmllciA9PT0gaWRlbnRpZmllcikge1xuICAgICAgICAvLyAgIHJldHVybiBjb250ZW50Lm1pbWVUeXBlXG4gICAgICAgIC8vIH1cbiAgICAgICAgLy8gYmlnIGJsdW5kZXIgaW4gZGF0YVxuICAgICAgICAvLyB0aGlzLmxvZ2dlci5sb2coY29udGVudC5pZGVudGlmaWVyLCAnV3JvbmcgbWltZXR5cGVzIGZvciByZXN1bWUnKVxuICAgICAgICByZXR1cm4gY29udGVudC5taW1lVHlwZVxuICAgICAgfVxuICAgICAgY29uc3QgZmxhdExpc3Q6IGFueVtdID0gW11cbiAgICAgIGNvbnN0IGdldEFsbEl0ZW1zUGVyQ2hpbGRyZW46IGFueSA9IChpdGVtOiBOc0NvbnRlbnQuSUNvbnRlbnQpID0+IHtcbiAgICAgICAgZmxhdExpc3QucHVzaChpdGVtKVxuICAgICAgICBpZiAoaXRlbS5jaGlsZHJlbikge1xuICAgICAgICAgIHJldHVybiBpdGVtLmNoaWxkcmVuLm1hcCgoaTogTnNDb250ZW50LklDb250ZW50KSA9PiBnZXRBbGxJdGVtc1BlckNoaWxkcmVuKGkpKVxuICAgICAgICB9XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgICAgZ2V0QWxsSXRlbXNQZXJDaGlsZHJlbihjb250ZW50KVxuICAgICAgY29uc3QgY2hsZCA9IF8uZmlyc3QoXy5maWx0ZXIoZmxhdExpc3QsIHsgaWRlbnRpZmllciB9KSlcbiAgICAgIHJldHVybiAoY2hsZCAmJiBjaGxkLm1pbWVUeXBlKSB8fCAnJ1xuICAgIH1cbiAgICAvLyByZXR1cm4gY2hsZC5taW1lVHlwZVxuICAgIHJldHVybiBOc0NvbnRlbnQuRU1pbWVUeXBlcy5VTktOT1dOXG4gIH1cblxuICBnZXRUb2NTdHJ1Y3R1cmUoXG4gICAgY29udGVudDogTnNDb250ZW50LklDb250ZW50LFxuICAgIHRvY1N0cnVjdHVyZTogTnNBcHBUb2MuSVRvY1N0cnVjdHVyZSxcbiAgKTogTnNBcHBUb2MuSVRvY1N0cnVjdHVyZSB7XG4gICAgaWYgKFxuICAgICAgY29udGVudCAmJlxuICAgICAgIShjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gdGhpcy5wcmltYXJ5Q2F0ZWdvcnkuUkVTT1VSQ0VcbiAgICAgICAgLy8gfHwgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHRoaXMucHJpbWFyeUNhdGVnb3J5LktOT1dMRURHRV9BUlRJRkFDVClcbiAgICAgICAgfHwgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHRoaXMucHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFXG4gICAgICAgIHx8IGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSB0aGlzLnByaW1hcnlDYXRlZ29yeS5GSU5BTF9BU1NFU1NNRU5UXG4gICAgICAgIHx8IGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSB0aGlzLnByaW1hcnlDYXRlZ29yeS5PRkZMSU5FX1NFU1NJT05cbiAgICAgICkpIHtcbiAgICAgIGlmIChjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuQ09VUlNFKSB7XG4gICAgICAgIHRvY1N0cnVjdHVyZS5jb3Vyc2UgKz0gMVxuICAgICAgfSBlbHNlIGlmIChjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuTU9EVUxFKSB7XG4gICAgICAgIHRvY1N0cnVjdHVyZS5sZWFybmluZ01vZHVsZSArPSAxXG4gICAgICB9XG4gICAgICBfLmVhY2goY29udGVudC5jaGlsZHJlbiwgY2hpbGQgPT4ge1xuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6IG5vLXBhcmFtZXRlci1yZWFzc2lnbm1lbnRcbiAgICAgICAgdG9jU3RydWN0dXJlID0gdGhpcy5nZXRUb2NTdHJ1Y3R1cmUoY2hpbGQsIHRvY1N0cnVjdHVyZSlcbiAgICAgIH0pXG4gICAgfSBlbHNlIGlmIChcbiAgICAgIGNvbnRlbnQgJiZcbiAgICAgIChcbiAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LlJFU09VUkNFXG4gICAgICAgIC8vIHx8IGNvbnRlbnQuY29udGVudFR5cGUgPT09ICdLbm93bGVkZ2UgQXJ0aWZhY3QnXG4gICAgICAgIHx8IGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5QUkFDVElDRV9SRVNPVVJDRVxuICAgICAgICB8fCBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVFxuICAgICAgICB8fCBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuT0ZGTElORV9TRVNTSU9OKVxuICAgICkge1xuICAgICAgc3dpdGNoIChjb250ZW50Lm1pbWVUeXBlKSB7XG4gICAgICAgIC8vIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuSEFORFNfT046XG4gICAgICAgIC8vICAgdG9jU3RydWN0dXJlLmhhbmRzT24gKz0gMVxuICAgICAgICAvLyAgIGJyZWFrXG4gICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuTVAzOlxuICAgICAgICAgIHRvY1N0cnVjdHVyZS5wb2RjYXN0ICs9IDFcbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLk1QNDpcbiAgICAgICAgY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5NM1U4OlxuICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLllPVVRVQkU6XG4gICAgICAgICAgdG9jU3RydWN0dXJlLnZpZGVvICs9IDFcbiAgICAgICAgICBicmVha1xuICAgICAgICAvLyBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLklOVEVSQUNUSU9OOlxuICAgICAgICAvLyAgIHRvY1N0cnVjdHVyZS5pbnRlcmFjdGl2ZVZpZGVvICs9IDFcbiAgICAgICAgLy8gICBicmVha1xuICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLlBERjpcbiAgICAgICAgICB0b2NTdHJ1Y3R1cmUucGRmICs9IDFcbiAgICAgICAgICBicmVha1xuICAgICAgICAvLyBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLkhUTUw6XG4gICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuVEVYVF9XRUI6XG4gICAgICAgICAgdG9jU3RydWN0dXJlLndlYlBhZ2UgKz0gMVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuU1VSVkVZOlxuICAgICAgICAgIHRvY1N0cnVjdHVyZS5zdXJ2ZXkgKz0gMVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuUVVJWjpcbiAgICAgICAgY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5BUFBMSUNBVElPTl9KU09OOlxuICAgICAgICAgIC8vIGlmIChjb250ZW50LnJlc291cmNlVHlwZSA9PT0gJ0Fzc2Vzc21lbnQnKSB7XG4gICAgICAgICAgdG9jU3RydWN0dXJlLmFzc2Vzc21lbnQgKz0gMVxuICAgICAgICAgIC8vIH0gZWxzZSB7XG4gICAgICAgICAgLy8gICB0b2NTdHJ1Y3R1cmUucXVpeiArPSAxXG4gICAgICAgICAgLy8gfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuT0ZGTElORV9TRVNTSU9OOlxuICAgICAgICAgIC8vIGlmIChjb250ZW50LnJlc291cmNlVHlwZSA9PT0gJ0Fzc2Vzc21lbnQnKSB7XG4gICAgICAgICAgdG9jU3RydWN0dXJlLm9mZmxpbmVTZXNzaW9uICs9IDFcbiAgICAgICAgICAvLyB9IGVsc2Uge1xuICAgICAgICAgIC8vICAgdG9jU3RydWN0dXJlLnF1aXogKz0gMVxuICAgICAgICAgIC8vIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLlBSQUNUSUNFX1JFU09VUkNFOlxuICAgICAgICAgIGlmIChjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gdGhpcy5wcmltYXJ5Q2F0ZWdvcnkuUFJBQ1RJQ0VfUkVTT1VSQ0UpIHtcbiAgICAgICAgICAgIHRvY1N0cnVjdHVyZS5wcmFjdGljZVRlc3QgKz0gMVxuICAgICAgICAgIH0gZWxzZSBpZiAoY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHRoaXMucHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQpIHtcbiAgICAgICAgICAgIHRvY1N0cnVjdHVyZS5maW5hbFRlc3QgKz0gMVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICAvLyBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLldFQl9NT0RVTEU6XG4gICAgICAgIC8vICAgdG9jU3RydWN0dXJlLndlYk1vZHVsZSArPSAxXG4gICAgICAgIC8vICAgYnJlYWtcbiAgICAgICAgY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5aSVAyOlxuICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLlpJUDpcbiAgICAgICAgICB0b2NTdHJ1Y3R1cmUuaW50ZXJhY3RpdmVjb250ZW50ICs9IDFcbiAgICAgICAgICBicmVha1xuICAgICAgICAvLyBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLllPVVRVQkU6XG4gICAgICAgIC8vICAgdG9jU3RydWN0dXJlLnlvdXR1YmUgKz0gMVxuICAgICAgICAvLyAgIGJyZWFrXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdG9jU3RydWN0dXJlLm90aGVyICs9IDFcbiAgICAgICAgICBicmVha1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRvY1N0cnVjdHVyZVxuICAgIH1cbiAgICByZXR1cm4gdG9jU3RydWN0dXJlXG4gIH1cblxuICBmaWx0ZXJUb2MoXG4gICAgY29udGVudDogTnNDb250ZW50LklDb250ZW50LFxuICAgIGZpbHRlckNhdGVnb3J5OiBOc0NvbnRlbnQuRUZpbHRlckNhdGVnb3J5ID0gTnNDb250ZW50LkVGaWx0ZXJDYXRlZ29yeS5BTEwsXG4gICk6IE5zQ29udGVudC5JQ29udGVudCB8IG51bGwge1xuICAgIGlmIChjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuUkVTT1VSQ0VcbiAgICAgIC8vICB8fCBjb250ZW50LmNvbnRlbnRUeXBlID09PSAnS25vd2xlZGdlIEFydGlmYWN0J1xuICAgICAgfHwgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFXG4gICAgICB8fCBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVFxuICAgICAgfHwgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk9GRkxJTkVfU0VTU0lPTikge1xuICAgICAgcmV0dXJuIHRoaXMuZmlsdGVyVW5pdENvbnRlbnQoY29udGVudCwgZmlsdGVyQ2F0ZWdvcnkpID8gY29udGVudCA6IG51bGxcbiAgICB9XG4gICAgY29uc3QgZmlsdGVyZWRDaGlsZHJlbjogTnNDb250ZW50LklDb250ZW50W10gPVxuICAgICAgXy5tYXAoXy5nZXQoY29udGVudCwgJ2NoaWxkcmVuJyksIGNoaWxkQ29udGVudCA9PlxuICAgICAgICB0aGlzLmZpbHRlclRvYyhjaGlsZENvbnRlbnQsIGZpbHRlckNhdGVnb3J5KSlcbiAgICAgICAgLmZpbHRlcih1bml0Q29udGVudCA9PiBCb29sZWFuKHVuaXRDb250ZW50KSkgYXMgTnNDb250ZW50LklDb250ZW50W11cbiAgICBpZiAoZmlsdGVyZWRDaGlsZHJlbiAmJiBmaWx0ZXJlZENoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uY29udGVudCxcbiAgICAgICAgY2hpbGRyZW46IGZpbHRlcmVkQ2hpbGRyZW4sXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsXG4gIH1cblxuICBmaWx0ZXJVbml0Q29udGVudChcbiAgICBjb250ZW50OiBOc0NvbnRlbnQuSUNvbnRlbnQsXG4gICAgZmlsdGVyQ2F0ZWdvcnk6IE5zQ29udGVudC5FRmlsdGVyQ2F0ZWdvcnkgPSBOc0NvbnRlbnQuRUZpbHRlckNhdGVnb3J5LkFMTCxcbiAgKTogYm9vbGVhbiB7XG4gICAgc3dpdGNoIChmaWx0ZXJDYXRlZ29yeSkge1xuICAgICAgY2FzZSBOc0NvbnRlbnQuRUZpbHRlckNhdGVnb3J5LkxFQVJOOlxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICFOc0NvbnRlbnRDb25zdGFudHMuVkFMSURfUFJBQ1RJQ0VfUkVTT1VSQ0VTLmhhcyhjb250ZW50LnJlc291cmNlVHlwZSkgJiZcbiAgICAgICAgICAhTnNDb250ZW50Q29uc3RhbnRzLlZBTElEX0FTU0VTU01FTlRfUkVTT1VSQ0VTLmhhcyhjb250ZW50LnJlc291cmNlVHlwZSlcbiAgICAgICAgKVxuICAgICAgY2FzZSBOc0NvbnRlbnQuRUZpbHRlckNhdGVnb3J5LlBSQUNUSUNFOlxuICAgICAgICByZXR1cm4gTnNDb250ZW50Q29uc3RhbnRzLlZBTElEX1BSQUNUSUNFX1JFU09VUkNFUy5oYXMoY29udGVudC5yZXNvdXJjZVR5cGUpXG4gICAgICBjYXNlIE5zQ29udGVudC5FRmlsdGVyQ2F0ZWdvcnkuQVNTRVNTOlxuICAgICAgICByZXR1cm4gTnNDb250ZW50Q29uc3RhbnRzLlZBTElEX0FTU0VTU01FTlRfUkVTT1VSQ0VTLmhhcyhjb250ZW50LnJlc291cmNlVHlwZSlcbiAgICAgIGNhc2UgTnNDb250ZW50LkVGaWx0ZXJDYXRlZ29yeS5BTEw6XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cbiAgfVxuICBmZXRjaENvbnRlbnRBbmFseXRpY3NDbGllbnREYXRhKGNvbnRlbnRJZDogc3RyaW5nKSB7XG4gICAgaWYgKHRoaXMuYW5hbHl0aWNzRmV0Y2hTdGF0dXMgIT09ICdmZXRjaGluZycgJiYgdGhpcy5hbmFseXRpY3NGZXRjaFN0YXR1cyAhPT0gJ2RvbmUnKSB7XG4gICAgICB0aGlzLmdldENvbnRlbnRBbmFseXRpY3NDbGllbnQoY29udGVudElkKVxuICAgIH1cbiAgfVxuICBwcml2YXRlIGdldENvbnRlbnRBbmFseXRpY3NDbGllbnQoY29udGVudElkOiBzdHJpbmcpIHtcbiAgICB0aGlzLmFuYWx5dGljc0ZldGNoU3RhdHVzID0gJ2ZldGNoaW5nJ1xuICAgIGNvbnN0IHVybCA9IGAke1BST1hZX1NMQUdfVjh9L0xBL2FwaS9sYS9jb250ZW50YW5hbHl0aWNzP2NvbnRlbnRfaWQ9JHtjb250ZW50SWR9JnR5cGU9Y291cnNlYFxuICAgIHRoaXMuaHR0cC5nZXQodXJsKS5zdWJzY3JpYmUoXG4gICAgICAocmVzdWx0OiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy5hbmFseXRpY3NGZXRjaFN0YXR1cyA9ICdkb25lJ1xuICAgICAgICB0aGlzLmFuYWx5dGljc1JlcGxheVN1YmplY3QubmV4dChyZXN1bHQpXG4gICAgICB9LFxuICAgICAgKCkgPT4ge1xuICAgICAgICB0aGlzLmFuYWx5dGljc1JlcGxheVN1YmplY3QubmV4dChudWxsKVxuICAgICAgICB0aGlzLmFuYWx5dGljc0ZldGNoU3RhdHVzID0gJ2RvbmUnXG4gICAgICB9LFxuICAgIClcbiAgfVxuXG4gIGZldGNoQ29udGVudEFuYWx5dGljc0RhdGEoY29udGVudElkOiBzdHJpbmcpIHtcbiAgICBpZiAodGhpcy5hbmFseXRpY3NGZXRjaFN0YXR1cyAhPT0gJ2ZldGNoaW5nJyAmJiB0aGlzLmFuYWx5dGljc0ZldGNoU3RhdHVzICE9PSAnZG9uZScpIHtcbiAgICAgIHRoaXMuZ2V0Q29udGVudEFuYWx5dGljcyhjb250ZW50SWQpXG4gICAgfVxuICB9XG4gIHByaXZhdGUgZ2V0Q29udGVudEFuYWx5dGljcyhjb250ZW50SWQ6IHN0cmluZykge1xuICAgIHRoaXMuYW5hbHl0aWNzRmV0Y2hTdGF0dXMgPSAnZmV0Y2hpbmcnXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOiBtYXgtbGluZS1sZW5ndGhcbiAgICBjb25zdCB1cmwgPSBgJHtQUk9YWV9TTEFHX1Y4fS9MQS9MQS9hcGkvVXNlcnM/cmVmaW5lbWVudGZpbHRlcj0ke2VuY29kZVVSSUNvbXBvbmVudChcbiAgICAgICdcInNvdXJjZVwiOltcImlHb3RcIixcIkxlYXJuaW5nIEh1YlwiXScsXG4gICAgKX0kJHtlbmNvZGVVUklDb21wb25lbnQoYFwiY291cnNlQ29kZVwiOiBbXCIke2NvbnRlbnRJZH1cIl1gKX1gXG4gICAgdGhpcy5odHRwLmdldCh1cmwpLnN1YnNjcmliZShcbiAgICAgIChyZXN1bHQ6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLmFuYWx5dGljc0ZldGNoU3RhdHVzID0gJ2RvbmUnXG4gICAgICAgIHRoaXMuYW5hbHl0aWNzUmVwbGF5U3ViamVjdC5uZXh0KHJlc3VsdClcbiAgICAgIH0sXG4gICAgICAoKSA9PiB7XG4gICAgICAgIHRoaXMuYW5hbHl0aWNzUmVwbGF5U3ViamVjdC5uZXh0KG51bGwpXG4gICAgICAgIHRoaXMuYW5hbHl0aWNzRmV0Y2hTdGF0dXMgPSAnZG9uZSdcbiAgICAgIH0sXG4gICAgKVxuICB9XG5cbiAgY2xlYXJBbmFseXRpY3NEYXRhKCkge1xuICAgIGlmICh0aGlzLmFuYWx5dGljc1JlcGxheVN1YmplY3QpIHtcbiAgICAgIHRoaXMuYW5hbHl0aWNzUmVwbGF5U3ViamVjdC51bnN1YnNjcmliZSgpXG4gICAgfVxuICB9XG5cbiAgZmV0Y2hDb250ZW50UGFyZW50cyhjb250ZW50SWQ6IHN0cmluZyk6IE9ic2VydmFibGU8TnNDb250ZW50LklDb250ZW50TWluaW1hbFtdPiB7XG4gICAgLy8gcmV0dXJuIHRoaXMuaHR0cC5nZXQ8TnNDb250ZW50LklDb250ZW50TWluaW1hbFtdPihcbiAgICAvLyAgIGAke0FQSV9FTkRfUE9JTlRTLkNPTlRFTlRfUEFSRU5UU30vJHtjb250ZW50SWR9YCxcbiAgICAvLyApXG4gICAgaWYgKGNvbnRlbnRJZCkgeyB9XG4gICAgcmV0dXJuIEVNUFRZXG4gIH1cbiAgZmV0Y2hDb250ZW50V2hhdHNOZXh0KFxuICAgIGNvbnRlbnRJZDogc3RyaW5nLFxuICAgIGNvbnRlbnRUeXBlPzogc3RyaW5nLFxuICApOiBPYnNlcnZhYmxlPE5zQ29udGVudC5JQ29udGVudE1pbmltYWxbXT4ge1xuICAgIGlmIChjb250ZW50VHlwZSkge1xuICAgICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8TnNDb250ZW50LklDb250ZW50TWluaW1hbFtdPihcbiAgICAgICAgYCR7QVBJX0VORF9QT0lOVFMuQ09OVEVOVF9ORVhUfS8ke2NvbnRlbnRJZH0/Y29udGVudFR5cGU9JHtjb250ZW50VHlwZX1gLFxuICAgICAgKVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5odHRwLmdldDxOc0NvbnRlbnQuSUNvbnRlbnRNaW5pbWFsW10+KFxuICAgICAgYCR7QVBJX0VORF9QT0lOVFMuQ09OVEVOVF9ORVhUfS8ke2NvbnRlbnRJZH0/dHM9JHtuZXcgRGF0ZSgpLmdldFRpbWUoKX1gLFxuICAgIClcbiAgfVxuXG4gIGZldGNoTW9yZUxpa2VUaGlzUGFpZChjb250ZW50SWQ6IHN0cmluZyk6IE9ic2VydmFibGU8TnNDb250ZW50LklDb250ZW50TWluaW1hbFtdPiB7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8TnNDb250ZW50LklDb250ZW50TWluaW1hbFtdPihcbiAgICAgIGAke0FQSV9FTkRfUE9JTlRTLkNPTlRFTlRfTkVYVFxuICAgICAgfS8ke2NvbnRlbnRJZH0/ZXhjbHVzaXZlQ29udGVudD10cnVlJnRzPSR7bmV3IERhdGUoKS5nZXRUaW1lKCl9YCxcbiAgICApXG4gIH1cblxuICBmZXRjaE1vcmVMaWtlVGhpc0ZyZWUoY29udGVudElkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPE5zQ29udGVudC5JQ29udGVudE1pbmltYWxbXT4ge1xuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PE5zQ29udGVudC5JQ29udGVudE1pbmltYWxbXT4oXG4gICAgICBgJHtBUElfRU5EX1BPSU5UUy5DT05URU5UX05FWFRcbiAgICAgIH0vJHtjb250ZW50SWR9P2V4Y2x1c2l2ZUNvbnRlbnQ9ZmFsc2UmdHM9JHtuZXcgRGF0ZSgpLmdldFRpbWUoKX1gLFxuICAgIClcbiAgfVxuXG4gIGZldGNoQ29udGVudENvaG9ydHMoXG4gICAgY29ob3J0VHlwZTogTnNDb2hvcnRzLkVDb2hvcnRUeXBlcyxcbiAgICBjb250ZW50SWQ6IHN0cmluZyxcbiAgKTogT2JzZXJ2YWJsZTxOc0NvaG9ydHMuSUNvaG9ydHNDb250ZW50W10+IHtcbiAgICByZXR1cm4gdGhpcy5odHRwLmdldDxOc0NvaG9ydHMuSUNvaG9ydHNDb250ZW50W10+KEFQSV9FTkRfUE9JTlRTLkNPSE9SVFMoY29ob3J0VHlwZSwgY29udGVudElkKSwge1xuICAgICAgaGVhZGVyczogeyByb290T3JnOiB0aGlzLmNvbmZpZ1N2Yy5yb290T3JnIHx8ICcnLCBvcmc6IHRoaXMuY29uZmlnU3ZjLm9yZyA/IHRoaXMuY29uZmlnU3ZjLm9yZ1swXSA6ICcnIH0sXG4gICAgfSlcbiAgfVxuICBmZXRjaEV4dGVybmFsQ29udGVudEFjY2Vzcyhjb250ZW50SWQ6IHN0cmluZyk6IE9ic2VydmFibGU8eyBoYXNBY2Nlc3M6IGJvb2xlYW4gfT4ge1xuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PHsgaGFzQWNjZXNzOiBib29sZWFuIH0+KEFQSV9FTkRfUE9JTlRTLkVYVEVSTkFMX0NPTlRFTlQoY29udGVudElkKSlcbiAgfVxuICBmZXRjaENvaG9ydEdyb3VwVXNlcnMoZ3JvdXBJZDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8TnNDb2hvcnRzLklDb2hvcnRzR3JvdXBVc2Vyc1tdPihBUElfRU5EX1BPSU5UUy5DT0hPUlRTX0dST1VQX1VTRVIoZ3JvdXBJZCkpXG4gIH1cbiAgZmV0Y2hNb3JlTGlrZVRoaXMoY29udGVudElkOiBzdHJpbmcsIGNvbnRlbnRUeXBlOiBzdHJpbmcpOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PE5zQ29udGVudC5JQ29udGVudFtdPihcbiAgICAgIEFQSV9FTkRfUE9JTlRTLlJFTEFURURfUkVTT1VSQ0UoY29udGVudElkLCBjb250ZW50VHlwZSksXG4gICAgKVxuICB9XG5cbiAgZmV0Y2hQb3N0QXNzZXNzbWVudFN0YXR1cyhjb250ZW50SWQ6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PHsgcmVzdWx0OiBOc0FwcFRvYy5JUG9zdEFzc2Vzc21lbnRbXSB9PihcbiAgICAgIEFQSV9FTkRfUE9JTlRTLlBPU1RfQVNTRVNTTUVOVChjb250ZW50SWQpLFxuICAgIClcbiAgfVxuXG4gIGZldGNoR2V0Q29udGVudERhdGEoY29udGVudElkOiBzdHJpbmcpIHtcbiAgICBsZXQgdXJsID0gJydcbiAgICBjb25zdCBmb3JQcmV2aWV3ID0gd2luZG93LmxvY2F0aW9uLmhyZWYuaW5jbHVkZXMoJy9wdWJsaWMvJykgfHwgd2luZG93LmxvY2F0aW9uLmhyZWYuaW5jbHVkZXMoJyZwcmV2aWV3PXRydWUnKVxuICAgIGlmICghZm9yUHJldmlldykge1xuICAgICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8eyByZXN1bHQ6IGFueSB9PihcbiAgICAgICAgQVBJX0VORF9QT0lOVFMuR0VUX0NPTlRFTlQoY29udGVudElkKSxcbiAgICAgIClcbiAgICB9XG4gICAgaWYgKHdpbmRvdy5sb2NhdGlvbi5ocmVmLmluY2x1ZGVzKCdlZGl0TW9kZT10cnVlJykgJiYgd2luZG93LmxvY2F0aW9uLmhyZWYuaW5jbHVkZXMoJ19yYycpKSB7XG4gICAgICB1cmwgPSBgL2FwaXMvcHJveGllcy92OC9hY3Rpb24vY29udGVudC92My9yZWFkLyR7Y29udGVudElkfWBcbiAgICB9IGVsc2Uge1xuICAgICAgdXJsID0gYC9hcGkvY29udGVudC92MS9yZWFkLyR7Y29udGVudElkfWBcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8eyByZXN1bHQ6IGFueSB9Pih1cmwpXG5cbiAgfVxuXG4gIGZldGNoQ29udGVudFBhcmVudChjb250ZW50SWQ6IHN0cmluZywgZGF0YTogTnNBcHBUb2MuSUNvbnRlbnRQYXJlbnRSZXEsIGZvclByZXZpZXcgPSBmYWxzZSkge1xuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdDxOc0FwcFRvYy5JQ29udGVudFBhcmVudFJlc3BvbnNlPihcbiAgICAgIGZvclByZXZpZXdcbiAgICAgICAgPyBBUElfRU5EX1BPSU5UUy5DT05URU5UX0FVVEhfUEFSRU5UKFxuICAgICAgICAgIGNvbnRlbnRJZCxcbiAgICAgICAgICB0aGlzLmNvbmZpZ1N2Yy5yb290T3JnIHx8ICcnLFxuICAgICAgICAgIHRoaXMuY29uZmlnU3ZjLm9yZyA/IHRoaXMuY29uZmlnU3ZjLm9yZ1swXSA6ICcnLFxuICAgICAgICApXG4gICAgICAgIDogQVBJX0VORF9QT0lOVFMuQ09OVEVOVF9QQVJFTlQoY29udGVudElkKSxcbiAgICAgIGRhdGEsXG4gICAgKVxuICB9XG5cbiAgY3JlYXRlQmF0Y2goYmF0Y2hEYXRhOiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3QoXG4gICAgICBBUElfRU5EX1BPSU5UUy5CQVRDSF9DUkVBVEUsXG4gICAgICB7IHJlcXVlc3Q6IGJhdGNoRGF0YSB9LFxuICAgIClcbiAgfVxuXG4gIGFzeW5jIG1hcENvbXBsZXRpb25QZXJjZW50YWdlUHJvZ3JhbShjb250ZW50OiBOc0NvbnRlbnQuSUNvbnRlbnQgfCBudWxsLCBlbnJvbG1lbnRMaXN0OiBhbnksIGNvbGxlY3Rpb25JZD86IHN0cmluZykge1xuICAgIHRoaXMuY29udGVudExvYWRlci5uZXh0KHRydWUpXG4gICAgbGV0IHRvdGFsQ291bnQgPSAwXG4gICAgbGV0IGxlYWZub2RlQ291bnQgPSAwXG4gICAgbGV0IGNvbXBsZXRlZExlYWZOb2RlczogYW55ID0gW11cbiAgICBsZXQgZmlyc3RVbmNvbXBsZXRlQ291cnNlOiBhbnkgPSAnJ1xuICAgIGxldCBpbnByb2dyZXNzRGF0YUNoZWNrOiBhbnkgPSBbXVxuICAgIGlmIChjb250ZW50ICYmIGNvbnRlbnQuY2hpbGRyZW4pIHtcbiAgICAgIGxlYWZub2RlQ291bnQgPSBjb250ZW50LmxlYWZOb2Rlc0NvdW50XG4gICAgICB0aGlzLmNvbnRlbnRMb2FkZXIubmV4dCh0cnVlKVxuICAgICAgY29uc3QgZm91bmRQYXJlbnRDb250ZW50ID0gdGhpcy5maW5kRW5yb2xtZW50QnlDb2xsZWN0aW9uSWQoZW5yb2xtZW50TGlzdCwgY29sbGVjdGlvbklkIHx8IGNvbnRlbnQuaWRlbnRpZmllcilcbiAgICAgIGlmIChmb3VuZFBhcmVudENvbnRlbnQgJiYgZm91bmRQYXJlbnRDb250ZW50LmNvbXBsZXRpb25QZXJjZW50YWdlID09PSAxMDApIHtcbiAgICAgICAgYXdhaXQgdGhpcy5tYXBDb21wbGV0aW9uQ2hpbGRQZXJjZW50YWdlUHJvZ3JhbShjb250ZW50KVxuICAgICAgICB0b3RhbENvdW50ID0gY29udGVudC5sZWFmTm9kZXNDb3VudFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGNvbnRlbnQ/LnByaW1hcnlDYXRlZ29yeSAhPT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuQ09VUlNFKSB7XG4gICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb250ZW50LmNoaWxkcmVuLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAvLyBjb250ZW50LmNoaWxkcmVuLmZvckVhY2goYXN5bmMgKHBhcmVudENoaWxkLGluZGV4KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwYXJlbnRDaGlsZCA9IGNvbnRlbnQuY2hpbGRyZW5baV1cbiAgICAgICAgICAgIGlmIChwYXJlbnRDaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LkNPVVJTRSkge1xuICAgICAgICAgICAgICBjb25zdCBmb3VuZENvbnRlbnQgPSB0aGlzLmZpbmRFbnJvbG1lbnRCeUNvbGxlY3Rpb25JZChlbnJvbG1lbnRMaXN0LCBwYXJlbnRDaGlsZD8uaWRlbnRpZmllcilcbiAgICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOiBtYXgtbGluZS1sZW5ndGhcbiAgICAgICAgICAgICAgLy8gdG90YWxDb3VudCA9IGZvdW5kQ29udGVudCAmJiBmb3VuZENvbnRlbnQuY29tcGxldGlvblBlcmNlbnRhZ2UgPyB0b3RhbENvdW50ICsgZm91bmRDb250ZW50LmNvbXBsZXRpb25QZXJjZW50YWdlIDogdG90YWxDb3VudCArIDBcbiAgICAgICAgICAgICAgLy8gY29udGVudC5jb21wbGV0aW9uUGVyY2VudGFnZSA9IE1hdGgucm91bmQodG90YWxDb3VudCAvIGxlYWZub2RlQ291bnQpXG4gICAgICAgICAgICAgIGlmIChmb3VuZENvbnRlbnQgJiYgZm91bmRDb250ZW50LmNvbXBsZXRpb25QZXJjZW50YWdlID09PSAxMDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRMb2FkZXIubmV4dCh0cnVlKVxuICAgICAgICAgICAgICAgIHRvdGFsQ291bnQgPSB0b3RhbENvdW50ICs9IHBhcmVudENoaWxkLmxlYWZOb2Rlc0NvdW50XG4gICAgICAgICAgICAgICAgY29tcGxldGVkTGVhZk5vZGVzID0gWy4uLmNvbXBsZXRlZExlYWZOb2RlcywgLi4ucGFyZW50Q2hpbGQubGVhZk5vZGVzXVxuICAgICAgICAgICAgICAgIGlmIChmb3VuZENvbnRlbnQuaXNzdWVkQ2VydGlmaWNhdGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGNlcnRpZmljYXRlOiBhbnkgPSBmb3VuZENvbnRlbnQuaXNzdWVkQ2VydGlmaWNhdGVzLnNvcnQoKGE6IGFueSwgYjogYW55KSA9PlxuICAgICAgICAgICAgICAgICAgICBuZXcgRGF0ZShhLmxhc3RJc3N1ZWRPbikuZ2V0VGltZSgpIC0gbmV3IERhdGUoYi5sYXN0SXNzdWVkT24pLmdldFRpbWUoKSlcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGNlcnRJZDogYW55ID0gY2VydGlmaWNhdGVbMF0uaWRlbnRpZmllclxuICAgICAgICAgICAgICAgICAgcGFyZW50Q2hpbGQuaXNzdWVkQ2VydGlmaWNhdGVzSWQgPSBjZXJ0SWRcbiAgICAgICAgICAgICAgICAgIC8vIGNvbnN0IGNlcnREYXRhOiBhbnkgPSBhd2FpdCB0aGlzLmRvd29ubG9hZENlcnRpZmljYXRlKGNlcnRJZCkudG9Qcm9taXNlKCkuY2F0Y2goX2Vycm9yID0+IHtcbiAgICAgICAgICAgICAgICAgIC8vICAgdGhpcy5jb250ZW50TG9hZGVyLm5leHQoZmFsc2UpXG4gICAgICAgICAgICAgICAgICAvLyB9KVxuICAgICAgICAgICAgICAgICAgLy8gaWYgKGNlcnREYXRhICYmIGNlcnREYXRhLnJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgLy8gICBwYXJlbnRDaGlsZC5pc3N1ZWRDZXJ0aWZpY2F0ZXNTVkcgPSBjZXJ0RGF0YS5yZXN1bHQucHJpbnRVcmlcbiAgICAgICAgICAgICAgICAgIC8vIH1cbiAgICAgICAgICAgICAgICAgIHRoaXMuY29udGVudExvYWRlci5uZXh0KGZhbHNlKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBwYXJlbnRDaGlsZC5jb21wbGV0aW9uUGVyY2VudGFnZSA9IDEwMFxuICAgICAgICAgICAgICAgIHBhcmVudENoaWxkLmNvbXBsZXRpb25TdGF0dXMgPSAyXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5tYXBDb21wbGV0aW9uQ2hpbGRQZXJjZW50YWdlUHJvZ3JhbShwYXJlbnRDaGlsZClcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAoZm91bmRDb250ZW50KSB7XG4gICAgICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRMb2FkZXIubmV4dCh0cnVlKVxuICAgICAgICAgICAgICAgICAgY29uc3QgbGFuZ3VhZ2UgPSB0aGlzLmNvbnRlbnRMYW5nU3ZjLmdldENvbnRlbnRMYW5ndWFnZShwYXJlbnRDaGlsZClcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHJlcSA9IHtcbiAgICAgICAgICAgICAgICAgICAgcmVxdWVzdDoge1xuICAgICAgICAgICAgICAgICAgICAgIGJhdGNoSWQ6IGZvdW5kQ29udGVudC5iYXRjaC5iYXRjaElkLFxuICAgICAgICAgICAgICAgICAgICAgIHVzZXJJZDogZm91bmRDb250ZW50LnVzZXJJZCxcbiAgICAgICAgICAgICAgICAgICAgICBsYW5ndWFnZTogbGFuZ3VhZ2UsXG4gICAgICAgICAgICAgICAgICAgICAgY291cnNlSWQ6IGZvdW5kQ29udGVudC5jb2xsZWN0aW9uSWQsXG4gICAgICAgICAgICAgICAgICAgICAgY29udGVudElkczogW10sXG4gICAgICAgICAgICAgICAgICAgICAgZmllbGRzOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAncHJvZ3Jlc3NkZXRhaWxzJyxcbiAgICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgZmlyc3RVbmNvbXBsZXRlQ291cnNlID0gKHBhcmVudENoaWxkLmNvbXBsZXRpb25QZXJjZW50YWdlID09PSAwIHx8ICFwYXJlbnRDaGlsZC5jb21wbGV0aW9uUGVyY2VudGFnZSkgJiZcbiAgICAgICAgICAgICAgICAgICAgIWZpcnN0VW5jb21wbGV0ZUNvdXJzZSA/IHBhcmVudENoaWxkIDogZmlyc3RVbmNvbXBsZXRlQ291cnNlXG4gICAgICAgICAgICAgICAgICBpbnByb2dyZXNzRGF0YUNoZWNrID0gaW5wcm9ncmVzc0RhdGFDaGVja1xuICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5mZXRjaENvbnRlbnRIaXN0b3J5VjIocmVxKS50b1Byb21pc2UoKS50aGVuKChwcm9ncmVzc2RhdGE6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkYXRhOiBhbnkgPSBwcm9ncmVzc2RhdGFcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGEucmVzdWx0ICYmIGRhdGE/LnJlc3VsdD8uY29udGVudExpc3Q/Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb21wbGV0ZWRDb3VudCA9IGRhdGEucmVzdWx0LmNvbnRlbnRMaXN0LmZpbHRlcigoZWxlOiBhbnkpID0+IGVsZS5wcm9ncmVzcyA9PT0gMTAwKVxuICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2hlY2tDb21wbGV0ZWRMZWFmbm9kZXMoY29tcGxldGVkTGVhZk5vZGVzLCBjb21wbGV0ZWRDb3VudClcbiAgICAgICAgICAgICAgICAgICAgICB0b3RhbENvdW50ID0gY29tcGxldGVkTGVhZk5vZGVzLmxlbmd0aFxuICAgICAgICAgICAgICAgICAgICAgIGlucHJvZ3Jlc3NEYXRhQ2hlY2sgPSBbLi4uaW5wcm9ncmVzc0RhdGFDaGVjaywgLi4uZGF0YS5yZXN1bHQuY29udGVudExpc3RdXG4gICAgICAgICAgICAgICAgICAgICAgLy8gaW5wcm9ncmVzc0RhdGFDaGVjayA9IGlucHJvZ3Jlc3NEYXRhQ2hlY2sgPyBpbnByb2dyZXNzRGF0YUNoZWNrIDogIGRhdGEucmVzdWx0LmNvbnRlbnRMaXN0XG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVSZXN1bWFEYXRhKGlucHJvZ3Jlc3NEYXRhQ2hlY2spXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5tYXBDb21wbGV0aW9uUGVyY2VudGFnZShwYXJlbnRDaGlsZCwgZGF0YS5yZXN1bHQuY29udGVudExpc3QpXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5tYXBNb2R1bGVDb3VudChwYXJlbnRDaGlsZClcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hcE1vZHVsZUNvdW50KHBhcmVudENoaWxkKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBwcm9ncmVzc2RhdGFcbiAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRMb2FkZXIubmV4dChmYWxzZSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vICBlbHNlIHtcbiAgICAgICAgICAgIC8vICAgaWYgKGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ICE9PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5CTEVOREVEX1BST0dSQU0pIHtcbiAgICAgICAgICAgIC8vICAgICB0aGlzLmNvbnRlbnRMb2FkZXIubmV4dCh0cnVlKVxuICAgICAgICAgICAgLy8gICAgIGNvbnN0IGZvdW5kQ29udGVudCA9IGVucm9sbWVudExpc3QgJiYgZW5yb2xtZW50TGlzdC5maW5kKChlbDogYW55KSA9PiBlbC5jb2xsZWN0aW9uSWQgPT09IGNvbnRlbnQuaWRlbnRpZmllcilcbiAgICAgICAgICAgIC8vICAgICBpZiAoZm91bmRDb250ZW50KSB7XG4gICAgICAgICAgICAvLyAgICAgICBjb25zdCByZXEgPSB7XG4gICAgICAgICAgICAvLyAgICAgICAgIHJlcXVlc3Q6IHtcbiAgICAgICAgICAgIC8vICAgICAgICAgICBiYXRjaElkOiBmb3VuZENvbnRlbnQuYmF0Y2guYmF0Y2hJZCxcbiAgICAgICAgICAgIC8vICAgICAgICAgICB1c2VySWQ6IGZvdW5kQ29udGVudC51c2VySWQsXG4gICAgICAgICAgICAvLyAgICAgICAgICAgY291cnNlSWQ6IGZvdW5kQ29udGVudC5jb2xsZWN0aW9uSWQsXG4gICAgICAgICAgICAvLyAgICAgICAgICAgY29udGVudElkczogW10sXG4gICAgICAgICAgICAvLyAgICAgICAgICAgZmllbGRzOiBbXG4gICAgICAgICAgICAvLyAgICAgICAgICAgICAncHJvZ3Jlc3NkZXRhaWxzJyxcbiAgICAgICAgICAgIC8vICAgICAgICAgICBdLFxuICAgICAgICAgICAgLy8gICAgICAgICB9LFxuICAgICAgICAgICAgLy8gICAgICAgfVxuICAgICAgICAgICAgLy8gICAgICAgYXdhaXQgdGhpcy5mZXRjaENvbnRlbnRIaXN0b3J5VjIocmVxKS50b1Byb21pc2UoKS50aGVuKChwcm9ncmVzc2RhdGE6IGFueSkgPT4ge1xuICAgICAgICAgICAgLy8gICAgICAgICBjb25zdCBkYXRhOiBhbnkgID0gcHJvZ3Jlc3NkYXRhXG4gICAgICAgICAgICAvLyAgICAgICAgIGlmIChkYXRhLnJlc3VsdCAmJiBkYXRhLnJlc3VsdC5jb250ZW50TGlzdC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAvLyAgICAgICAgICAgY29uc3QgY29tcGxldGVkQ291bnQgPSBkYXRhLnJlc3VsdC5jb250ZW50TGlzdC5maWx0ZXIoKGVsZTogYW55KSA9PiBlbGUucHJvZ3Jlc3MgPT09IDEwMClcbiAgICAgICAgICAgIC8vICAgICAgICAgICB0aGlzLmNoZWNrQ29tcGxldGVkTGVhZm5vZGVzKGNvbXBsZXRlZExlYWZOb2RlcywgY29tcGxldGVkQ291bnQpXG4gICAgICAgICAgICAvLyAgICAgICAgICAgdG90YWxDb3VudCA9IGNvbXBsZXRlZExlYWZOb2Rlcy5sZW5ndGhcbiAgICAgICAgICAgIC8vICAgICAgICAgICBpbnByb2dyZXNzRGF0YUNoZWNrID0gaW5wcm9ncmVzc0RhdGFDaGVjayA/IGlucHJvZ3Jlc3NEYXRhQ2hlY2sgOiAgZGF0YS5yZXN1bHQuY29udGVudExpc3RcbiAgICAgICAgICAgIC8vICAgICAgICAgICB0aGlzLnVwZGF0ZVJlc3VtYURhdGEoaW5wcm9ncmVzc0RhdGFDaGVjaylcbiAgICAgICAgICAgIC8vICAgICAgICAgICB0aGlzLm1hcENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQsIGRhdGEucmVzdWx0LmNvbnRlbnRMaXN0KVxuICAgICAgICAgICAgLy8gICAgICAgICB9XG4gICAgICAgICAgICAvLyAgICAgICAgIHRoaXMuY29udGVudExvYWRlci5uZXh0KGZhbHNlKVxuICAgICAgICAgICAgLy8gICAgICAgICByZXR1cm4gcHJvZ3Jlc3NkYXRhXG4gICAgICAgICAgICAvLyAgICAgICB9KVxuICAgICAgICAgICAgLy8gICAgIH1cbiAgICAgICAgICAgIC8vICAgICB0aGlzLmNvbnRlbnRMb2FkZXIubmV4dChmYWxzZSlcbiAgICAgICAgICAgIC8vICAgfVxuICAgICAgICAgICAgLy8gfVxuICAgICAgICAgICAgdGhpcy5jb250ZW50TG9hZGVyLm5leHQoZmFsc2UpXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuQkxFTkRFRF9QUk9HUkFNXG4gICAgICAgICAgfHwgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LkNPVVJTRVxuICAgICAgICAgIHx8IGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5TVEFOREFMT05FX0FTU0VTU01FTlRcbiAgICAgICAgICB8fCBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuQ1VSQVRFRF9QUk9HUkFNKSB7XG4gICAgICAgICAgLy8gdGhpcy5tYXBDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50LCB0aGlzLnJlc3VtZURhdGEpXG4gICAgICAgICAgY29uc3QgZm91bmRQYXJlbnRDb250ZW50ID0gdGhpcy5maW5kRW5yb2xtZW50QnlDb2xsZWN0aW9uSWQoZW5yb2xtZW50TGlzdCwgY29sbGVjdGlvbklkIHx8IGNvbnRlbnQ/LmlkZW50aWZpZXIpXG4gICAgICAgICAgY29uc3QgbGFuZ3VhZ2UgPSB0aGlzLmNvbnRlbnRMYW5nU3ZjLmdldENvbnRlbnRMYW5ndWFnZShjb250ZW50KVxuICAgICAgICAgIGNvbnN0IHJlcSA9IHtcbiAgICAgICAgICAgIHJlcXVlc3Q6IHtcbiAgICAgICAgICAgICAgYmF0Y2hJZDogZm91bmRQYXJlbnRDb250ZW50Py5iYXRjaD8uYmF0Y2hJZCxcbiAgICAgICAgICAgICAgdXNlcklkOiBmb3VuZFBhcmVudENvbnRlbnQ/LnVzZXJJZCxcbiAgICAgICAgICAgICAgY291cnNlSWQ6IGZvdW5kUGFyZW50Q29udGVudD8uY29sbGVjdGlvbklkLFxuICAgICAgICAgICAgICBsYW5ndWFnZTogbGFuZ3VhZ2UsXG4gICAgICAgICAgICAgIGNvbnRlbnRJZHM6IFtdLFxuICAgICAgICAgICAgICBmaWVsZHM6IFtcbiAgICAgICAgICAgICAgICAncHJvZ3Jlc3NkZXRhaWxzJyxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfVxuICAgICAgICAgIGF3YWl0IHRoaXMuZmV0Y2hDb250ZW50SGlzdG9yeVYyKHJlcSkudG9Qcm9taXNlKCkudGhlbigocHJvZ3Jlc3NkYXRhOiBhbnkpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGRhdGE6IGFueSA9IHByb2dyZXNzZGF0YVxuICAgICAgICAgICAgaWYgKGRhdGEgJiYgZGF0YS5yZXN1bHQgJiYgZGF0YS5yZXN1bHQuY29udGVudExpc3QubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICBjb25zdCBjb21wbGV0ZWRDb3VudCA9IGRhdGEucmVzdWx0LmNvbnRlbnRMaXN0LmZpbHRlcigoZWxlOiBhbnkpID0+IGVsZS5wcm9ncmVzcyA9PT0gMTAwKVxuICAgICAgICAgICAgICB0aGlzLmNoZWNrQ29tcGxldGVkTGVhZm5vZGVzKGNvbXBsZXRlZExlYWZOb2RlcywgY29tcGxldGVkQ291bnQpXG4gICAgICAgICAgICAgIHRvdGFsQ291bnQgPSBjb21wbGV0ZWRMZWFmTm9kZXMubGVuZ3RoXG4gICAgICAgICAgICAgIGlucHJvZ3Jlc3NEYXRhQ2hlY2sgPSBbLi4uaW5wcm9ncmVzc0RhdGFDaGVjaywgLi4uZGF0YS5yZXN1bHQuY29udGVudExpc3RdXG4gICAgICAgICAgICAgIC8vIGlucHJvZ3Jlc3NEYXRhQ2hlY2sgPSBpbnByb2dyZXNzRGF0YUNoZWNrID8gaW5wcm9ncmVzc0RhdGFDaGVjayA6ICBkYXRhLnJlc3VsdC5jb250ZW50TGlzdFxuICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVJlc3VtYURhdGEoaW5wcm9ncmVzc0RhdGFDaGVjaylcbiAgICAgICAgICAgICAgdGhpcy5tYXBDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50LCBkYXRhLnJlc3VsdC5jb250ZW50TGlzdClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuY29udGVudExvYWRlci5uZXh0KGZhbHNlKVxuICAgICAgICAgICAgcmV0dXJuIHByb2dyZXNzZGF0YVxuICAgICAgICAgIH0pXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaW5wcm9ncmVzc0RhdGFDaGVjayAmJiBpbnByb2dyZXNzRGF0YUNoZWNrLmxlbmd0aCA9PT0gMCAmJiBmaXJzdFVuY29tcGxldGVDb3Vyc2UpIHtcbiAgICAgICAgICBjb25zdCBmaXJzdENoaWxkRGF0YSA9IHRoaXMud2lkZ2V0U3ZjLmdldEZpcnN0Q2hpbGRJbkhpZXJhcmNoeShmaXJzdFVuY29tcGxldGVDb3Vyc2UpXG4gICAgICAgICAgY29uc3QgY2hpbGRFbnJvbGxtZW50RGF0YSA9IGVucm9sbWVudExpc3QuZmluZCgoZWw6IGFueSkgPT5cbiAgICAgICAgICAgIGVsLmNvbGxlY3Rpb25JZCA9PT0gZmlyc3RVbmNvbXBsZXRlQ291cnNlLmlkZW50aWZpZXIpXG4gICAgICAgICAgY29uc3QgcmVzdW1lRGF0YSA9IFt7XG4gICAgICAgICAgICBjb250ZW50SWQ6IGZpcnN0Q2hpbGREYXRhLmlkZW50aWZpZXIsXG4gICAgICAgICAgICBiYXRjaElkOiBjaGlsZEVucm9sbG1lbnREYXRhICYmIGNoaWxkRW5yb2xsbWVudERhdGEuYmF0Y2hJZCxcbiAgICAgICAgICAgIGNvbXBsZXRlZENvdW50OiAxLFxuICAgICAgICAgICAgY29tcGxldGlvblBlcmNlbnRhZ2U6IDAuMCxcbiAgICAgICAgICAgIHByb2dyZXNzOiAwLFxuICAgICAgICAgICAgdmlld0NvdW50OiAxLFxuICAgICAgICAgICAgY291cnNlSWQ6IGNoaWxkRW5yb2xsbWVudERhdGEgJiYgY2hpbGRFbnJvbGxtZW50RGF0YS5jb3Vyc2VJZCxcbiAgICAgICAgICAgIGNvbGxlY3Rpb25JZDogY2hpbGRFbnJvbGxtZW50RGF0YSAmJiBjaGlsZEVucm9sbG1lbnREYXRhLmNvdXJzZUlkLFxuICAgICAgICAgICAgc3RhdHVzOiAxLFxuICAgICAgICAgIH1dXG4gICAgICAgICAgaW5wcm9ncmVzc0RhdGFDaGVjayA9IHJlc3VtZURhdGFcbiAgICAgICAgICB0aGlzLnVwZGF0ZVJlc3VtYURhdGEoaW5wcm9ncmVzc0RhdGFDaGVjaylcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gY29uc3QgcGFyZW50Q29udGVudCA9IGVucm9sbWVudExpc3QuZmluZCgoZWw6IGFueSkgPT4gZWwuY29sbGVjdGlvbklkID09PSBjb250ZW50LmlkZW50aWZpZXIpXG4gICAgICAvLyBpZiAoIXBhcmVudENvbnRlbnQuY29tcGxldGlvblBlcmNlbnRhZ2UpIHtcbiAgICAgIGNvbnN0IGNhbGN1bGF0ZWRQY3QgPSBNYXRoLmZsb29yKCh0b3RhbENvdW50IC8gbGVhZm5vZGVDb3VudCkgKiAxMDApXG4gICAgICBjb250ZW50LmNvbXBsZXRpb25QZXJjZW50YWdlID0gaXNOYU4oY2FsY3VsYXRlZFBjdCkgPyAwIDogY2FsY3VsYXRlZFBjdFxuICAgICAgY29udGVudC5jb21wbGV0aW9uU3RhdHVzID0gY29udGVudC5jb21wbGV0aW9uUGVyY2VudGFnZSA+PSAxMDAgPyAyIDogKGNvbnRlbnQuY29tcGxldGlvblBlcmNlbnRhZ2UgPiAwID8gMSA6IDApXG4gICAgICBpZiAoY29udGVudC5jb21wbGV0aW9uUGVyY2VudGFnZSA9PT0gMTAwICYmIGlucHJvZ3Jlc3NEYXRhQ2hlY2sgJiYgaW5wcm9ncmVzc0RhdGFDaGVjay5sZW5ndGggPT09IDAgJiYgIWZpcnN0VW5jb21wbGV0ZUNvdXJzZSkge1xuICAgICAgICBjb25zdCBmaXJzdENoaWxkRGF0YSA9IHRoaXMud2lkZ2V0U3ZjLmdldEZpcnN0Q2hpbGRJbkhpZXJhcmNoeShjb250ZW50KVxuICAgICAgICBjb25zdCBjaGlsZEVucm9sbG1lbnREYXRhID0gZW5yb2xtZW50TGlzdC5maW5kKChlbDogYW55KSA9PlxuICAgICAgICAgIGVsLmNvbGxlY3Rpb25JZCA9PT0gY29udGVudC5jaGlsZHJlblswXS5pZGVudGlmaWVyKVxuICAgICAgICBjb25zdCByZXN1bWVEYXRhID0gW3tcbiAgICAgICAgICBjb250ZW50SWQ6IGZpcnN0Q2hpbGREYXRhLmlkZW50aWZpZXIsXG4gICAgICAgICAgYmF0Y2hJZDogY2hpbGRFbnJvbGxtZW50RGF0YSAmJiBjaGlsZEVucm9sbG1lbnREYXRhLmJhdGNoSWQsXG4gICAgICAgICAgY29tcGxldGVkQ291bnQ6IDEsXG4gICAgICAgICAgY29tcGxldGlvblBlcmNlbnRhZ2U6IDEwMCxcbiAgICAgICAgICBwcm9ncmVzczogMixcbiAgICAgICAgICB2aWV3Q291bnQ6IDEsXG4gICAgICAgICAgY291cnNlSWQ6IGNoaWxkRW5yb2xsbWVudERhdGEgJiYgY2hpbGRFbnJvbGxtZW50RGF0YS5jb3Vyc2VJZCxcbiAgICAgICAgICBjb2xsZWN0aW9uSWQ6IGNoaWxkRW5yb2xsbWVudERhdGEgJiYgY2hpbGRFbnJvbGxtZW50RGF0YS5jb3Vyc2VJZCxcbiAgICAgICAgICBzdGF0dXM6IDIsXG4gICAgICAgIH1dXG4gICAgICAgIGlucHJvZ3Jlc3NEYXRhQ2hlY2sgPSByZXN1bWVEYXRhXG4gICAgICAgIHRoaXMudXBkYXRlUmVzdW1hRGF0YShpbnByb2dyZXNzRGF0YUNoZWNrKVxuICAgICAgfVxuICAgICAgLy8gLy8gfSBlbHNlIHtcbiAgICAgIC8vICAgY29udGVudC5jb21wbGV0aW9uUGVyY2VudGFnZSA9IHBhcmVudENvbnRlbnQuY29tcGxldGlvblBlcmNlbnRhZ2VcbiAgICAgIC8vIC8vIH1cbiAgICAgIC8vIH0pXG4gICAgICAvLyB0aGlzLm1hcE1vZHVsZUR1cmF0aW9uQW5kUHJvZ3Jlc3MoY29udGVudCwgY29udGVudClcbiAgICAgIHRoaXMuY2FsbEhpcmFyY2h5UHJvZ3Jlc3NIYXNobWFwKGNvbnRlbnQpXG4gICAgICB0aGlzLmNoZWNrTW9kdWxlV2lzZURhdGEoY29udGVudClcbiAgICAgIC8vIENvbXB1dGUgbWlsZXN0b25lIGxvY2tpbmcgQUZURVIgcHJvZ3Jlc3MgZGF0YSBpcyBwb3B1bGF0ZWRcbiAgICAgIGlmIChjb250ZW50LmNvdXJzZUNhdGVnb3J5ID09PSAnTGVhcm5pbmcgUGF0aHdheScpIHtcbiAgICAgICAgdGhpcy5jb21wdXRlTWlsZXN0b25lTG9ja2luZ1N0YXR1cygpXG4gICAgICAgIC8vIEVuc3VyZSBoYXNobWFwIHVwZGF0ZXMgYXJlIHB1Ymxpc2hlZCBmb3IgY2hhbmdlIGRldGVjdGlvblxuICAgICAgICB0aGlzLmhhc2htYXAgPSB7IC4uLnRoaXMuaGFzaG1hcCB9XG4gICAgICB9XG4gICAgICB0aGlzLmNvbnRlbnRMb2FkZXIubmV4dChmYWxzZSlcbiAgICB9XG4gIH1cbiAgY2hlY2tDb21wbGV0ZWRMZWFmbm9kZXMobGVhZk5vZGVzOiBhbnksIGNvbXBsZXRlZENvdW50OiBhbnkpIHtcbiAgICBpZiAoY29tcGxldGVkQ291bnQubGVuZ3RoID4gMCkge1xuICAgICAgY29tcGxldGVkQ291bnQuZm9yRWFjaCgoZWxlOiBhbnkpID0+IHtcbiAgICAgICAgaWYgKCFsZWFmTm9kZXMuaW5jbHVkZXMoZWxlLmNvbnRlbnRJZCkpIHtcbiAgICAgICAgICBsZWFmTm9kZXMucHVzaChlbGUuY29udGVudElkKVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIC8vIGFzeW5jIGdldFByb2dyZXNzRm9yQ2hpbGRDb3Vyc2UocmVxdWVzdDogYW55LCBjb250ZW50OiBhbnkpIHtcbiAgLy8gIGNvbnN0IGRhdGE6IGFueSA9ICAgYXdhaXQgdGhpcy5mZXRjaENvbnRlbnRIaXN0b3J5VjIocmVxdWVzdCkudG9Qcm9taXNlKCkuY2F0Y2goX2Vycm9yID0+IHt9KVxuICAvLyAgIGlmIChkYXRhLnJlc3VsdCAmJiBkYXRhLnJlc3VsdC5jb250ZW50TGlzdC5sZW5ndGggPiAwKSB7XG4gIC8vICAgICB0aGlzLm1hcENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQsIGRhdGEucmVzdWx0LmNvbnRlbnRMaXN0KVxuICAvLyB9XG4gIC8vIH1cblxuICBmaW5kRW5yb2xtZW50QnlDb2xsZWN0aW9uSWQoZW5yb2xtZW50TGlzdDogYW55LCBpZGVudGlmaWVyOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gZW5yb2xtZW50TGlzdCAmJiBlbnJvbG1lbnRMaXN0Py5sZW5ndGggJiYgZW5yb2xtZW50TGlzdC5maW5kKChlbDogYW55KSA9PiBlbD8uY29sbGVjdGlvbklkID09PSBpZGVudGlmaWVyKVxuICB9XG5cbiAgYXN5bmMgbWFwQ29tcGxldGlvbkNoaWxkUGVyY2VudGFnZVByb2dyYW0oY291cnNlOiBhbnkpIHtcbiAgICBpZiAoY291cnNlICYmIGNvdXJzZS5jaGlsZHJlbikge1xuICAgICAgYXdhaXQgY291cnNlLmNoaWxkcmVuLm1hcChhc3luYyAoY291cnNlQ2hpbGQ6IGFueSkgPT4ge1xuICAgICAgICBpZiAoKGNvdXJzZUNoaWxkICYmIGNvdXJzZUNoaWxkLmNoaWxkcmVuKSB8fCBjb3Vyc2VDaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk1PRFVMRSkge1xuICAgICAgICAgIHRoaXMubWFwQ29tcGxldGlvbkNoaWxkUGVyY2VudGFnZVByb2dyYW0oY291cnNlQ2hpbGQpXG4gICAgICAgICAgY291cnNlWydtb2R1bGVDb3VudCddID0gY291cnNlWydtb2R1bGVDb3VudCddID8gY291cnNlWydtb2R1bGVDb3VudCddICsgMSA6IDFcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb3Vyc2VDaGlsZFsnY29tcGxldGlvblBlcmNlbnRhZ2UnXSA9IDEwMFxuICAgICAgICAgIGNvdXJzZUNoaWxkWydjb21wbGV0aW9uU3RhdHVzJ10gPSAyXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgcHVibGljIG1hcE1vZHVsZUR1cmF0aW9uQW5kUHJvZ3Jlc3MoY29udGVudDogTnNDb250ZW50LklDb250ZW50IHwgbnVsbCwgcGFyZW50OiBOc0NvbnRlbnQuSUNvbnRlbnQgfCBudWxsKSB7XG4gICAgaWYgKGNvbnRlbnQgJiYgY29udGVudC5jaGlsZHJlbikge1xuICAgICAgaWYgKGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5NT0RVTEUpIHtcbiAgICAgICAgLy8gY29udGVudC5jaGlsZHJlbi5tYXAoKGl0ZW06IE5zQ29udGVudC5JQ29udGVudCk9PiB7XG4gICAgICAgIC8qIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSAqL1xuICAgICAgICBjb250ZW50ID0gdGhpcy5nZXRDYWxjdWxhdGlvbnNGcm9tQ2hpbGRyZW4oY29udGVudClcbiAgICAgICAgLy8gfSlcbiAgICAgIH1cblxuICAgICAgY29udGVudC5jaGlsZHJlbi5tYXAoKGl0ZW06IE5zQ29udGVudC5JQ29udGVudCkgPT4ge1xuICAgICAgICAvLyBpZiAoaXRlbS5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk1PRFVMRSkge1xuICAgICAgICAvLyAgIHRoaXMubWFwTW9kdWxlRHVyYXRpb25BbmRQcm9ncmVzcyhpdGVtLCBwYXJlbnQpXG4gICAgICAgIC8vIH0gZWxzZSB7XG4gICAgICAgIC8vICAgdGhpcy5tYXBNb2R1bGVEdXJhdGlvbkFuZFByb2dyZXNzKGl0ZW0sIHBhcmVudClcbiAgICAgICAgLy8gfVxuICAgICAgICBpZiAoaXRlbSAmJiBpdGVtLmNoaWxkcmVuKSB7XG4gICAgICAgICAgdGhpcy5tYXBNb2R1bGVEdXJhdGlvbkFuZFByb2dyZXNzKGl0ZW0sIHBhcmVudClcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgY3JlYXRlSGlyYXJjaHlQcm9ncmVzc0hhc2htYXAoaGllcmFyY2h5RGF0YTogTnNDb250ZW50LklDb250ZW50LCByb290Q291cnNlQ2F0ZWdvcnk/OiBzdHJpbmcpIHtcbiAgICBpZiAoaGllcmFyY2h5RGF0YSAmJiBoaWVyYXJjaHlEYXRhLmNoaWxkcmVuKSB7XG4gICAgICBoaWVyYXJjaHlEYXRhLmNoaWxkcmVuLmZvckVhY2goKGNoaWxkOiBOc0NvbnRlbnQuSUNvbnRlbnQpID0+IHtcbiAgICAgICAgaWYgKGNoaWxkICYmIGNoaWxkLmNoaWxkcmVuKSB7XG4gICAgICAgICAgdGhpcy5jcmVhdGVIaXJhcmNoeVByb2dyZXNzSGFzaG1hcChjaGlsZCwgcm9vdENvdXJzZUNhdGVnb3J5KVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHByaW1hcnlDYXQgPSBjaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgYXMgc3RyaW5nXG4gICAgICAgIGNvbnN0IGNvdXJzZUNhdCA9IChjaGlsZC5jb3Vyc2VDYXRlZ29yeSB8fCBjaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgfHwgJycpIGFzIHN0cmluZ1xuICAgICAgICBjb25zdCBpc01pbGVzdG9uZSA9IHByaW1hcnlDYXQgPT09ICdNaWxlc3RvbmUnIHx8IGNvdXJzZUNhdCA9PT0gJ01pbGVzdG9uZSdcbiAgICAgICAgY29uc3QgaXNDb2xsZWN0aW9uID0gY2hpbGQubWltZVR5cGUgPT09IE5zQ29udGVudC5FTWltZVR5cGVzLkNPTExFQ1RJT05cbiAgICAgICAgY29uc3QgaXNNb2R1bGUgPSBjaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk1PRFVMRVxuICAgICAgICBjb25zdCBpc1Jlc291cmNlID0gY2hpbGQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5SRVNPVVJDRSB8fFxuICAgICAgICAgIGNoaWxkLnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuUFJBQ1RJQ0VfUkVTT1VSQ0UgfHxcbiAgICAgICAgICBjaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICBjaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LkNPTVBfQVNTRVNTTUVOVFxuICAgICAgICBjb25zdCBpc0xlYXJuaW5nUGF0aHdheSA9IHJvb3RDb3Vyc2VDYXRlZ29yeSA9PT0gJ0xlYXJuaW5nIFBhdGh3YXknXG5cbiAgICAgICAgLy8gQ2hlY2sgaWYgY29udGVudCBpcyBtYW5kYXRvcnkgKGlzTWFuZGF0b3J5IGZsYWcgb3IgbWFuZGF0b3J5IHByb3BlcnR5KVxuICAgICAgICBjb25zdCBpc01hbmRhdG9yeSA9IGNoaWxkLmlzTWFuZGF0b3J5ID09PSB0cnVlIHx8IChjaGlsZCBhcyBhbnkpLm1hbmRhdG9yeSA9PT0gdHJ1ZVxuXG4gICAgICAgIGxldCBsb2NhbE1hcDogYW55ID0ge1xuICAgICAgICAgIHBhcmVudDogY2hpbGQ/LnBhcmVudCxcbiAgICAgICAgICBpZGVudGlmaWVyOiBjaGlsZC5pZGVudGlmaWVyLFxuICAgICAgICAgIGxlYWZOb2Rlc0NvdW50OiBjaGlsZC5sZWFmTm9kZXNDb3VudCB8fCBudWxsLFxuICAgICAgICAgIGxlYWZOb2RlczogY2hpbGQubGVhZk5vZGVzIHx8IFtdLFxuICAgICAgICAgIGNvbXBsZXRpb25QZXJjZW50YWdlOiBjaGlsZC5jb21wbGV0aW9uUGVyY2VudGFnZSB8fCBjaGlsZC5wcm9ncmVzcyB8fCAwLFxuICAgICAgICAgIGNvbXBsZXRpb25TdGF0dXM6IGNoaWxkLmNvbXBsZXRpb25TdGF0dXMgfHwgY2hpbGQuc3RhdHVzIHx8IDAsXG4gICAgICAgICAgc3RhdHVzOiBjaGlsZC5zdGF0dXMgfHwgY2hpbGQuY29tcGxldGlvblN0YXR1cyB8fCAwLFxuICAgICAgICAgIHByb2dyZXNzOiBjaGlsZC5wcm9ncmVzcyxcbiAgICAgICAgICBwcmltYXJ5Q2F0ZWdvcnk6IGNoaWxkLnByaW1hcnlDYXRlZ29yeSxcbiAgICAgICAgICBjb3Vyc2VDYXRlZ29yeTogY291cnNlQ2F0LFxuICAgICAgICAgIGR1cmF0aW9uOiBjaGlsZC5kdXJhdGlvbiB8fCAwLFxuICAgICAgICAgIGV4cGVjdGVkRHVyYXRpb246IGNoaWxkLmV4cGVjdGVkRHVyYXRpb24gfHwgMCxcbiAgICAgICAgICAvLyBBZGRpdGlvbmFsIG1ldGFkYXRhIGZvciBwZXJmb3JtYW5jZSBvcHRpbWl6YXRpb25cbiAgICAgICAgICBtaW1lVHlwZTogY2hpbGQubWltZVR5cGUsXG4gICAgICAgICAgaXNMb2NrZWQ6IGNoaWxkLmlzTG9ja2VkIHx8IGZhbHNlLFxuICAgICAgICAgIGFydGlmYWN0VXJsOiBjaGlsZC5hcnRpZmFjdFVybCB8fCBudWxsLFxuICAgICAgICAgIG5hbWU6IGNoaWxkLm5hbWUgfHwgJycsXG4gICAgICAgICAgY29udGVudFR5cGU6IGNoaWxkLmNvbnRlbnRUeXBlIHx8ICcnLFxuICAgICAgICAgIC8vIFByZS1jb21wdXRlZCBmbGFncyBmb3IgTGVhcm5pbmcgUGF0aHdheVxuICAgICAgICAgIGlzTWlsZXN0b25lOiBpc01pbGVzdG9uZSxcbiAgICAgICAgICBpc0NvbGxlY3Rpb246IGlzQ29sbGVjdGlvbixcbiAgICAgICAgICBpc01vZHVsZTogaXNNb2R1bGUsXG4gICAgICAgICAgaXNSZXNvdXJjZTogaXNSZXNvdXJjZSxcbiAgICAgICAgICBpc0xlYXJuaW5nUGF0aHdheTogaXNMZWFybmluZ1BhdGh3YXksXG4gICAgICAgICAgaXNNYW5kYXRvcnk6IGlzTWFuZGF0b3J5LFxuICAgICAgICAgIC8vIE1pbGVzdG9uZSBzcGVjaWZpYyBkYXRhXG4gICAgICAgICAgbWlsZXN0b25lSW5kZXg6IChjaGlsZCBhcyBhbnkpLm1pbGVzdG9uZUluZGV4LFxuICAgICAgICAgIGNvbXBsZXRlZExlYWZOb2Rlc0NvdW50OiAoY2hpbGQgYXMgYW55KS5jb21wbGV0ZWRMZWFmTm9kZXNDb3VudCB8fCAwLFxuICAgICAgICAgIC8vIFByZS1hc3Nlc3NtZW50IGZsYWcgKGZvciBtaWxlc3RvbmUgZ2F0aW5nKVxuICAgICAgICAgIGlzUHJlQXNzZXNzbWVudDogKGNoaWxkIGFzIGFueSkuaXNQcmVBc3Nlc3NtZW50IHx8IGZhbHNlLFxuICAgICAgICB9XG5cbiAgICAgICAgLy8gRGVidWcgbG9nZ2luZyBmb3IgbWlsZXN0b25lc1xuICAgICAgICBpZiAoaXNNaWxlc3RvbmUpIHtcbiAgICAgICAgICAvLyBQcm9ncmVzcyB0cmFja2VkIGZvciBtaWxlc3RvbmVcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuaGFzaG1hcFtjaGlsZC5pZGVudGlmaWVyXSA9IGxvY2FsTWFwXG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBjcmVhdGVQcmVBc3Nlc3NtZW50SGlyYXJjaHlQcm9ncmVzc0hhc2htYXAoaGllcmFyY2h5RGF0YTogTnNDb250ZW50LklDb250ZW50KSB7XG4gICAgaWYgKGhpZXJhcmNoeURhdGEgJiYgaGllcmFyY2h5RGF0YS5wcmVFbnJvbG1lbnRSZXNvdXJjZXMpIHtcbiAgICAgIGhpZXJhcmNoeURhdGEucHJlRW5yb2xtZW50UmVzb3VyY2VzLmZvckVhY2goKGNoaWxkOiBOc0NvbnRlbnQuSUNvbnRlbnQpID0+IHtcbiAgICAgICAgaWYgKGNoaWxkICYmIGNoaWxkLnByZUVucm9sbWVudFJlc291cmNlcykge1xuICAgICAgICAgIHRoaXMuY3JlYXRlUHJlQXNzZXNzbWVudEhpcmFyY2h5UHJvZ3Jlc3NIYXNobWFwKGNoaWxkKVxuICAgICAgICB9XG4gICAgICAgIGxldCBsb2NhbE1hcCA9IHt9XG4gICAgICAgIGxvY2FsTWFwID0ge1xuICAgICAgICAgIHBhcmVudDogY2hpbGQ/LnBhcmVudCxcbiAgICAgICAgICBpZGVudGlmaWVyOiBjaGlsZC5pZGVudGlmaWVyLFxuICAgICAgICAgIGxlYWZOb2Rlc0NvdW50OiBjaGlsZC5sZWFmTm9kZXNDb3VudCB8fCBudWxsLFxuICAgICAgICAgIGxlYWZOb2RlczogY2hpbGQubGVhZk5vZGVzIHx8IFtdLFxuICAgICAgICAgIGNvbXBsZXRpb25QZXJjZW50YWdlOiBjaGlsZC5jb21wbGV0aW9uUGVyY2VudGFnZSB8fCBjaGlsZC5wcm9ncmVzcyxcbiAgICAgICAgICBjb21wbGV0aW9uU3RhdHVzOiBjaGlsZC5jb21wbGV0aW9uU3RhdHVzLFxuICAgICAgICAgIHN0YXR1czogY2hpbGQuc3RhdHVzIHx8IGNoaWxkLmNvbXBsZXRpb25TdGF0dXMgfHwgMCxcbiAgICAgICAgICBwcm9ncmVzczogY2hpbGQucHJvZ3Jlc3MsXG4gICAgICAgICAgcHJpbWFyeUNhdGVnb3J5OiBjaGlsZC5wcmltYXJ5Q2F0ZWdvcnksXG4gICAgICAgICAgY291cnNlQ2F0ZWdvcnk6IGNoaWxkLmNvdXJzZUNhdGVnb3J5IHx8IGNoaWxkLnByaW1hcnlDYXRlZ29yeSB8fCAnJyxcbiAgICAgICAgICBkdXJhdGlvbjogY2hpbGQuZHVyYXRpb24gfHwgMCxcbiAgICAgICAgICBleHBlY3RlZER1cmF0aW9uOiBjaGlsZC5leHBlY3RlZER1cmF0aW9uIHx8IDAsXG4gICAgICAgICAgLy8gTWFyayBhcyBwcmUtYXNzZXNzbWVudCBPTkxZIGlmIGV4cGxpY2l0bHkgc2V0IC0gZG8gTk9UIGRlZmF1bHQgdG8gdHJ1ZVxuICAgICAgICAgIGlzUHJlQXNzZXNzbWVudDogY2hpbGQuaXNQcmVBc3Nlc3NtZW50IHx8IGZhbHNlLFxuICAgICAgICB9XG4gICAgICAgIHRoaXMuaGFzaG1hcFtjaGlsZC5pZGVudGlmaWVyXSA9IGxvY2FsTWFwXG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBjYWxsSGlyYXJjaHlQcm9ncmVzc0hhc2htYXAoaGllcmFyY2h5RGF0YTogTnNDb250ZW50LklDb250ZW50IHwgbnVsbCkge1xuICAgIGlmIChoaWVyYXJjaHlEYXRhKSB7XG4gICAgICBjb25zdCByb290Q291cnNlQ2F0ZWdvcnkgPSBoaWVyYXJjaHlEYXRhLmNvdXJzZUNhdGVnb3J5IHx8IGhpZXJhcmNoeURhdGEucHJpbWFyeUNhdGVnb3J5IHx8ICcnXG4gICAgICBjb25zdCBpc0xlYXJuaW5nUGF0aHdheSA9IHJvb3RDb3Vyc2VDYXRlZ29yeSA9PT0gJ0xlYXJuaW5nIFBhdGh3YXknXG5cbiAgICAgIHRoaXMuaGFzaG1hcFtoaWVyYXJjaHlEYXRhLmlkZW50aWZpZXJdID0ge1xuICAgICAgICBwYXJlbnQ6IGhpZXJhcmNoeURhdGEucGFyZW50LFxuICAgICAgICBpZGVudGlmaWVyOiBoaWVyYXJjaHlEYXRhLmlkZW50aWZpZXIsXG4gICAgICAgIGxlYWZOb2Rlc0NvdW50OiBoaWVyYXJjaHlEYXRhLmxlYWZOb2Rlc0NvdW50IHx8IG51bGwsXG4gICAgICAgIGxlYWZOb2RlczogaGllcmFyY2h5RGF0YS5sZWFmTm9kZXMgfHwgW10sXG4gICAgICAgIGNvbXBsZXRpb25QZXJjZW50YWdlOiBoaWVyYXJjaHlEYXRhLmNvbXBsZXRpb25QZXJjZW50YWdlIHx8IGhpZXJhcmNoeURhdGEucHJvZ3Jlc3MgfHwgMCxcbiAgICAgICAgY29tcGxldGlvblN0YXR1czogaGllcmFyY2h5RGF0YS5jb21wbGV0aW9uU3RhdHVzIHx8IDAsXG4gICAgICAgIHByb2dyZXNzOiBoaWVyYXJjaHlEYXRhLnByb2dyZXNzLFxuICAgICAgICBwcmltYXJ5Q2F0ZWdvcnk6IGhpZXJhcmNoeURhdGEucHJpbWFyeUNhdGVnb3J5LFxuICAgICAgICBjb3Vyc2VDYXRlZ29yeTogcm9vdENvdXJzZUNhdGVnb3J5LFxuICAgICAgICBleHBlY3RlZER1cmF0aW9uOiBoaWVyYXJjaHlEYXRhLmV4cGVjdGVkRHVyYXRpb24gfHwgMCxcbiAgICAgICAgLy8gQWRkaXRpb25hbCBtZXRhZGF0YVxuICAgICAgICBtaW1lVHlwZTogaGllcmFyY2h5RGF0YS5taW1lVHlwZSxcbiAgICAgICAgaXNMb2NrZWQ6IGhpZXJhcmNoeURhdGEuaXNMb2NrZWQgfHwgZmFsc2UsXG4gICAgICAgIGFydGlmYWN0VXJsOiBoaWVyYXJjaHlEYXRhLmFydGlmYWN0VXJsIHx8IG51bGwsXG4gICAgICAgIG5hbWU6IGhpZXJhcmNoeURhdGEubmFtZSB8fCAnJyxcbiAgICAgICAgY29udGVudFR5cGU6IGhpZXJhcmNoeURhdGEuY29udGVudFR5cGUgfHwgJycsXG4gICAgICAgIGlzTWlsZXN0b25lOiBmYWxzZSxcbiAgICAgICAgaXNDb2xsZWN0aW9uOiBoaWVyYXJjaHlEYXRhLm1pbWVUeXBlID09PSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5DT0xMRUNUSU9OLFxuICAgICAgICBpc01vZHVsZTogaGllcmFyY2h5RGF0YS5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk1PRFVMRSxcbiAgICAgICAgaXNSZXNvdXJjZTogZmFsc2UsXG4gICAgICAgIGlzTGVhcm5pbmdQYXRod2F5OiBpc0xlYXJuaW5nUGF0aHdheSxcbiAgICAgIH1cbiAgICAgIGlmIChoaWVyYXJjaHlEYXRhLnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuQ1VSQVRFRF9QUk9HUkFNICYmXG4gICAgICAgIGhpZXJhcmNoeURhdGEuY29tcGF0aWJpbGl0eUxldmVsID49IDUgJiYgaGllcmFyY2h5RGF0YS5jb250ZXh0TG9ja2luZ1R5cGUgJiZcbiAgICAgICAgaGllcmFyY2h5RGF0YS5jb250ZXh0TG9ja2luZ1R5cGUgPT09IE5zQ29udGVudC5FQ29udGV4dExvY2tpbmdUeXBlLkNPVVJTRV9BU1NFU1NNRU5UX09OTFkpIHtcbiAgICAgICAgdGhpcy5oYXNobWFwW2hpZXJhcmNoeURhdGEuaWRlbnRpZmllcl0gPSB7XG4gICAgICAgICAgLi4udGhpcy5oYXNobWFwW2hpZXJhcmNoeURhdGEuaWRlbnRpZmllcl0sXG4gICAgICAgICAgY29udGV4dExvY2tpbmdUeXBlOiBoaWVyYXJjaHlEYXRhLmNvbnRleHRMb2NraW5nVHlwZSxcbiAgICAgICAgICBjb21wYXRpYmlsaXR5TGV2ZWw6IGhpZXJhcmNoeURhdGEuY29tcGF0aWJpbGl0eUxldmVsLFxuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLmNyZWF0ZUhpcmFyY2h5UHJvZ3Jlc3NIYXNobWFwKGhpZXJhcmNoeURhdGEsIHJvb3RDb3Vyc2VDYXRlZ29yeSlcbiAgICAgIC8vIE5PVEU6IGNvbXB1dGVNaWxlc3RvbmVMb2NraW5nU3RhdHVzIGlzIGNhbGxlZCBBRlRFUiBwcm9ncmVzcyBkYXRhIGlzIHBvcHVsYXRlZFxuICAgICAgLy8gaW4gbWFwQ29tcGxldGlvblBlcmNlbnRhZ2VQcm9ncmFtLCBub3QgaGVyZSB3aGVyZSBjb21wbGV0aW9uIGRhdGEgaXMgc3RpbGwgMFxuICAgICAgdGhpcy5oYXNobWFwID0geyAuLi50aGlzLmhhc2htYXAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQcmUtY29tcHV0ZSBtaWxlc3RvbmUgbG9ja2luZyBzdGF0dXMgZm9yIGFsbCBtaWxlc3RvbmVzIGluIExlYXJuaW5nIFBhdGh3YXlcbiAgICogVGhpcyBhdm9pZHMgZXhwZW5zaXZlIGNhbGN1bGF0aW9ucyBpbiBjb21wb25lbnQgZ2V0dGVyc1xuICAgKiBcbiAgICogTG9ja2luZyBSdWxlczpcbiAgICogMC4gSWYgdXNlciBpcyBub3QgZW5yb2xsZWQsIEFMTCBtaWxlc3RvbmVzIGFyZSBsb2NrZWRcbiAgICogMS4gQWxsIG1pbGVzdG9uZXMgYXJlIGxvY2tlZCBieSBkZWZhdWx0XG4gICAqIDIuIE1pbGVzdG9uZSAxIChNMSkgdW5sb2NrcyB3aGVuIHByZS1hc3Nlc3NtZW50IGlzIGNvbXBsZXRlZFxuICAgKiAzLiBNaWxlc3RvbmUgTiAoTiA+IDEpIHVubG9ja3Mgd2hlbjpcbiAgICogICAgLSBBbGwgbWFuZGF0b3J5IGxlYXJuaW5nIGl0ZW1zIGluIE1pbGVzdG9uZSBOLTEgYXJlIGNvbXBsZXRlZFxuICAgKiAgICAtIFRoZSBhc3Nlc3NtZW50IG9mIE1pbGVzdG9uZSBOLTEgaXMgY29tcGxldGVkXG4gICAqL1xuICBwdWJsaWMgY29tcHV0ZU1pbGVzdG9uZUxvY2tpbmdTdGF0dXMoaXNFbnJvbGxlZDogYm9vbGVhbiA9IHRydWUpIHtcbiAgICBpZiAoIXRoaXMuaGFzaG1hcCB8fCBPYmplY3Qua2V5cyh0aGlzLmhhc2htYXApLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIFxuICAgIGNvbnNvbGUubG9nKCc9PT0gY29tcHV0ZU1pbGVzdG9uZUxvY2tpbmdTdGF0dXMgPT09JylcbiAgICBjb25zb2xlLmxvZygnVXNlciBlbnJvbGxlZDonLCBpc0Vucm9sbGVkKVxuICAgIFxuICAgIC8vIENhcHR1cmUgaW5pdGlhbCBzdGF0ZSB0byBkZXRlY3QgY2hhbmdlc1xuICAgIGNvbnN0IGluaXRpYWxIYXNobWFwU25hcHNob3QgPSBKU09OLnN0cmluZ2lmeSh0aGlzLmhhc2htYXApXG4gICAgXG4gICAgLy8gR2V0IGFsbCBtaWxlc3RvbmUgZW50cmllcyBmcm9tIGhhc2htYXAgc29ydGVkIGJ5IHRoZWlyIGluZGV4IG9yIG51bWJlclxuICAgIGNvbnN0IG1pbGVzdG9uZUVudHJpZXMgPSBPYmplY3Qua2V5cyh0aGlzLmhhc2htYXApXG4gICAgICAuZmlsdGVyKGtleSA9PiB7XG4gICAgICAgIGNvbnN0IGl0ZW0gPSB0aGlzLmhhc2htYXBba2V5XVxuICAgICAgICByZXR1cm4gaXRlbS5pc01pbGVzdG9uZSB8fCBpdGVtLnByaW1hcnlDYXRlZ29yeSA9PT0gJ01pbGVzdG9uZScgfHwgaXRlbS5jb3Vyc2VDYXRlZ29yeSA9PT0gJ01pbGVzdG9uZSdcbiAgICAgIH0pXG4gICAgICAuc29ydCgoYSwgYikgPT4ge1xuICAgICAgICAvLyBTb3J0IGJ5IG1pbGVzdG9uZUluZGV4IGlmIGF2YWlsYWJsZSwgb3RoZXJ3aXNlIGJ5IG51bWJlciBpbiBJRFxuICAgICAgICBjb25zdCBpdGVtQSA9IHRoaXMuaGFzaG1hcFthXVxuICAgICAgICBjb25zdCBpdGVtQiA9IHRoaXMuaGFzaG1hcFtiXVxuICAgICAgICBpZiAoaXRlbUEubWlsZXN0b25lSW5kZXggIT09IHVuZGVmaW5lZCAmJiBpdGVtQi5taWxlc3RvbmVJbmRleCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcmV0dXJuIGl0ZW1BLm1pbGVzdG9uZUluZGV4IC0gaXRlbUIubWlsZXN0b25lSW5kZXhcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBudW1BID0gcGFyc2VJbnQoYS5yZXBsYWNlKC9cXEQvZywgJycpKSB8fCAwXG4gICAgICAgIGNvbnN0IG51bUIgPSBwYXJzZUludChiLnJlcGxhY2UoL1xcRC9nLCAnJykpIHx8IDBcbiAgICAgICAgcmV0dXJuIG51bUEgLSBudW1CXG4gICAgICB9KVxuXG4gICAgLy8gSWYgdXNlciBpcyBOT1QgZW5yb2xsZWQsIGxvY2sgQUxMIG1pbGVzdG9uZXNcbiAgICBpZiAoIWlzRW5yb2xsZWQpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdVc2VyIG5vdCBlbnJvbGxlZCAtIGxvY2tpbmcgQUxMIG1pbGVzdG9uZXMnKVxuICAgICAgbWlsZXN0b25lRW50cmllcy5mb3JFYWNoKG1pbGVzdG9uZUlkID0+IHtcbiAgICAgICAgdGhpcy5oYXNobWFwW21pbGVzdG9uZUlkXS5jb21wdXRlZElzTG9ja2VkID0gdHJ1ZVxuICAgICAgfSlcbiAgICAgIC8vIEFsc28gbG9jayBhbGwgY2hpbGRyZW5cbiAgICAgIE9iamVjdC5rZXlzKHRoaXMuaGFzaG1hcCkuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICBjb25zdCBpdGVtID0gdGhpcy5oYXNobWFwW2tleV1cbiAgICAgICAgaWYgKCFpdGVtLmlzTWlsZXN0b25lKSB7XG4gICAgICAgICAgdGhpcy5oYXNobWFwW2tleV0uaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQgPSB0cnVlXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICB0aGlzLmhhc2htYXAgPSB7IC4uLnRoaXMuaGFzaG1hcCB9XG4gICAgICB0aGlzLmhhc2htYXBVcGRhdGVkLm5leHQoeyB0aW1lc3RhbXA6IERhdGUubm93KCksIGhhc2htYXA6IHRoaXMuaGFzaG1hcCB9KVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgcHJlLWFzc2Vzc21lbnQgaXMgY29tcGxldGVkIChyZXF1aXJlZCB0byB1bmxvY2sgTTEpXG4gICAgY29uc3QgaXNQcmVBc3Nlc3NtZW50Q29tcGxldGVkID0gdGhpcy5jaGVja1ByZUFzc2Vzc21lbnRDb21wbGV0aW9uKClcblxuICAgIG1pbGVzdG9uZUVudHJpZXMuZm9yRWFjaCgobWlsZXN0b25lSWQsIGluZGV4KSA9PiB7XG4gICAgICBjb25zdCBtaWxlc3RvbmUgPSB0aGlzLmhhc2htYXBbbWlsZXN0b25lSWRdXG4gICAgICBpZiAoIW1pbGVzdG9uZSkgcmV0dXJuXG5cbiAgICAgIC8vIEZpcnN0IG1pbGVzdG9uZSAoTTEpIC0gdW5sb2NrcyB3aGVuIHByZS1hc3Nlc3NtZW50IGlzIGNvbXBsZXRlZFxuICAgICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICAgIHRoaXMuaGFzaG1hcFttaWxlc3RvbmVJZF0uY29tcHV0ZWRJc0xvY2tlZCA9ICFpc1ByZUFzc2Vzc21lbnRDb21wbGV0ZWRcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIC8vIEZvciBzdWJzZXF1ZW50IG1pbGVzdG9uZXMgKE0yLCBNMywgZXRjLiksIGNoZWNrIGlmIHByZXZpb3VzIG1pbGVzdG9uZSBpcyBmdWxseSBjb21wbGV0ZWRcbiAgICAgIGNvbnN0IHByZXZpb3VzTWlsZXN0b25lSWQgPSBtaWxlc3RvbmVFbnRyaWVzW2luZGV4IC0gMV1cbiAgICAgIGNvbnN0IHByZXZpb3VzTWlsZXN0b25lID0gdGhpcy5oYXNobWFwW3ByZXZpb3VzTWlsZXN0b25lSWRdXG5cbiAgICAgIGlmIChwcmV2aW91c01pbGVzdG9uZSkge1xuICAgICAgICAvLyBTSU1QTElGSUVEIEFQUFJPQUNIOiBDaGVjayBpZiBwcmV2aW91cyBtaWxlc3RvbmUgaXMgMTAwJSBjb21wbGV0ZVxuICAgICAgICAvLyBUaGlzIHVzZXMgdGhlIGFnZ3JlZ2F0ZWQgY29tcGxldGlvbiBwZXJjZW50YWdlIHdoaWNoIGlzIGFscmVhZHkgY2FsY3VsYXRlZFxuICAgICAgICAvLyBVc2UgTnVtYmVyKCkgdG8gZW5zdXJlIHByb3BlciBudW1lcmljIGNvbXBhcmlzb25cbiAgICAgICAgY29uc3QgcHJldkNvbXBsZXRpb25QY3QgPSBOdW1iZXIocHJldmlvdXNNaWxlc3RvbmUuY29tcGxldGlvblBlcmNlbnRhZ2UpIHx8IDBcbiAgICAgICAgY29uc3QgcHJldkNvbXBsZXRpb25TdGF0dXMgPSBOdW1iZXIocHJldmlvdXNNaWxlc3RvbmUuY29tcGxldGlvblN0YXR1cykgfHwgMFxuICAgICAgICBjb25zdCBwcmV2U3RhdHVzID0gTnVtYmVyKHByZXZpb3VzTWlsZXN0b25lLnN0YXR1cykgfHwgMFxuICAgICAgICBjb25zdCBwcmV2Q29tcGxldGVkTGVhZk5vZGVzID0gTnVtYmVyKHByZXZpb3VzTWlsZXN0b25lLmNvbXBsZXRlZExlYWZOb2Rlc0NvdW50KSB8fCAwXG4gICAgICAgIGNvbnN0IHByZXZMZWFmTm9kZXNDb3VudCA9IE51bWJlcihwcmV2aW91c01pbGVzdG9uZS5sZWFmTm9kZXNDb3VudCkgfHwgMFxuXG4gICAgICAgIGNvbnN0IHByZXZpb3VzTWlsZXN0b25lQ29tcGxldGUgPVxuICAgICAgICAgIHByZXZDb21wbGV0aW9uUGN0ID49IDEwMCB8fFxuICAgICAgICAgIHByZXZDb21wbGV0aW9uU3RhdHVzID09PSAyIHx8XG4gICAgICAgICAgcHJldlN0YXR1cyA9PT0gMiB8fFxuICAgICAgICAgIChwcmV2TGVhZk5vZGVzQ291bnQgPiAwICYmIHByZXZDb21wbGV0ZWRMZWFmTm9kZXMgPj0gcHJldkxlYWZOb2Rlc0NvdW50KVxuXG4gICAgICAgIC8vIElmIHNpbXBsZSBjaGVjayBkb2Vzbid0IHNob3cgY29tcGxldGUsIGZhbGwgYmFjayB0byBkZXRhaWxlZCBjaGVja1xuICAgICAgICBsZXQgY2FuVW5sb2NrID0gcHJldmlvdXNNaWxlc3RvbmVDb21wbGV0ZVxuXG4gICAgICAgIGlmICghY2FuVW5sb2NrKSB7XG4gICAgICAgICAgLy8gRmFsbGJhY2s6IENoZWNrIGluZGl2aWR1YWwgaXRlbXNcbiAgICAgICAgICBjb25zdCBpc1ByZXZpb3VzTWlsZXN0b25lQXNzZXNzbWVudENvbXBsZXRlID0gdGhpcy5jaGVja01pbGVzdG9uZUFzc2Vzc21lbnRDb21wbGV0ZShwcmV2aW91c01pbGVzdG9uZUlkKVxuICAgICAgICAgIGNvbnN0IGlzUHJldmlvdXNNaWxlc3RvbmVNYW5kYXRvcnlDb21wbGV0ZSA9IHRoaXMuY2hlY2tNaWxlc3RvbmVNYW5kYXRvcnlDb250ZW50Q29tcGxldGUocHJldmlvdXNNaWxlc3RvbmVJZClcbiAgICAgICAgICBjYW5VbmxvY2sgPSBpc1ByZXZpb3VzTWlsZXN0b25lQXNzZXNzbWVudENvbXBsZXRlICYmIGlzUHJldmlvdXNNaWxlc3RvbmVNYW5kYXRvcnlDb21wbGV0ZVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5oYXNobWFwW21pbGVzdG9uZUlkXS5jb21wdXRlZElzTG9ja2VkID0gIWNhblVubG9ja1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5oYXNobWFwW21pbGVzdG9uZUlkXS5jb21wdXRlZElzTG9ja2VkID0gdHJ1ZVxuICAgICAgfVxuICAgIH0pXG5cbiAgICAvLyBOb3cgY29tcHV0ZSBwYXJlbnQgbWlsZXN0b25lIGxvY2sgc3RhdHVzIGZvciBhbGwgY2hpbGRyZW5cbiAgICBPYmplY3Qua2V5cyh0aGlzLmhhc2htYXApLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGNvbnN0IGl0ZW0gPSB0aGlzLmhhc2htYXBba2V5XVxuICAgICAgaWYgKGl0ZW0uaXNNaWxlc3RvbmUpIHJldHVybiAvLyBTa2lwIG1pbGVzdG9uZXMgdGhlbXNlbHZlc1xuXG4gICAgICAvLyBUcmF2ZXJzZSB1cCB0byBmaW5kIGlmIGFueSBhbmNlc3RvciBtaWxlc3RvbmUgaXMgbG9ja2VkXG4gICAgICBsZXQgY3VycmVudFBhcmVudElkID0gaXRlbS5wYXJlbnRcbiAgICAgIGxldCBkZXB0aCA9IDBcbiAgICAgIGNvbnN0IG1heERlcHRoID0gNVxuXG4gICAgICB3aGlsZSAoY3VycmVudFBhcmVudElkICYmIGRlcHRoIDwgbWF4RGVwdGgpIHtcbiAgICAgICAgY29uc3QgcGFyZW50RGF0YSA9IHRoaXMuaGFzaG1hcFtjdXJyZW50UGFyZW50SWRdXG4gICAgICAgIGlmIChwYXJlbnREYXRhKSB7XG4gICAgICAgICAgaWYgKHBhcmVudERhdGEuaXNNaWxlc3RvbmUgJiYgcGFyZW50RGF0YS5jb21wdXRlZElzTG9ja2VkKSB7XG4gICAgICAgICAgICB0aGlzLmhhc2htYXBba2V5XS5pc1BhcmVudE1pbGVzdG9uZUxvY2tlZCA9IHRydWVcbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgfVxuICAgICAgICAgIGN1cnJlbnRQYXJlbnRJZCA9IHBhcmVudERhdGEucGFyZW50XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgICBkZXB0aCsrXG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMuaGFzaG1hcFtrZXldLmlzUGFyZW50TWlsZXN0b25lTG9ja2VkKSB7XG4gICAgICAgIHRoaXMuaGFzaG1hcFtrZXldLmlzUGFyZW50TWlsZXN0b25lTG9ja2VkID0gZmFsc2VcbiAgICAgIH1cbiAgICB9KVxuXG4gICAgLy8gQ3JlYXRlIG5ldyBoYXNobWFwIHJlZmVyZW5jZSB0byB0cmlnZ2VyIEFuZ3VsYXIgY2hhbmdlIGRldGVjdGlvblxuICAgIHRoaXMuaGFzaG1hcCA9IHsgLi4udGhpcy5oYXNobWFwIH1cbiAgICBcbiAgICAvLyBFbWl0IHVwZGF0ZSBldmVudCBpZiBoYXNobWFwIGNoYW5nZWQgKG1pbGVzdG9uZSBsb2NrIHN0YXR1cyB1cGRhdGVkKVxuICAgIGNvbnN0IGZpbmFsSGFzaG1hcFNuYXBzaG90ID0gSlNPTi5zdHJpbmdpZnkodGhpcy5oYXNobWFwKVxuICAgIGlmIChpbml0aWFsSGFzaG1hcFNuYXBzaG90ICE9PSBmaW5hbEhhc2htYXBTbmFwc2hvdCkge1xuICAgICAgdGhpcy5oYXNobWFwVXBkYXRlZC5uZXh0KHsgdGltZXN0YW1wOiBEYXRlLm5vdygpLCBoYXNobWFwOiB0aGlzLmhhc2htYXAgfSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVHJpZ2dlciBtaWxlc3RvbmUgbG9jayB1cGRhdGUgd2hlbiBoYXNobWFwIHByb2dyZXNzIGlzIHVwZGF0ZWQgZXh0ZXJuYWxseVxuICAgKiBDYWxsZWQgZnJvbSB2aWV3ZXItdXRpbC5zZXJ2aWNlLnRzIGFmdGVyIHByb2dyZXNzIHVwZGF0ZXNcbiAgICovXG4gIHB1YmxpYyB0cmlnZ2VyTWlsZXN0b25lTG9ja1VwZGF0ZSgpIHtcbiAgICAvLyBDaGVjayBpZiB3ZSBoYXZlIGEgTGVhcm5pbmcgUGF0aHdheSBpbiB0aGUgaGFzaG1hcFxuICAgIGNvbnN0IGhhc0xlYXJuaW5nUGF0aHdheSA9IE9iamVjdC5rZXlzKHRoaXMuaGFzaG1hcCkuc29tZShrZXkgPT4ge1xuICAgICAgY29uc3QgaXRlbSA9IHRoaXMuaGFzaG1hcFtrZXldXG4gICAgICByZXR1cm4gaXRlbS5pc0xlYXJuaW5nUGF0aHdheSAmJiBpdGVtLmNvdXJzZUNhdGVnb3J5ID09PSAnTGVhcm5pbmcgUGF0aHdheSdcbiAgICB9KVxuICAgIFxuICAgIGlmIChoYXNMZWFybmluZ1BhdGh3YXkpIHtcbiAgICAgIGNvbnNvbGUubG9nKCfwn5SEIFRyaWdnZXJpbmcgbWlsZXN0b25lIGxvY2sgcmVjb21wdXRhdGlvbiBhZnRlciBwcm9ncmVzcyB1cGRhdGUnKVxuICAgICAgLy8gQXNzdW1lIGVucm9sbGVkIHNpbmNlIHByb2dyZXNzIHdhcyBqdXN0IHVwZGF0ZWRcbiAgICAgIHRoaXMuY29tcHV0ZU1pbGVzdG9uZUxvY2tpbmdTdGF0dXModHJ1ZSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgcHJlLWFzc2Vzc21lbnQgKHByZWxpbWluYXJ5IGFzc2Vzc21lbnQpIGlzIGNvbXBsZXRlZFxuICAgKiBQcmUtYXNzZXNzbWVudCBpcyB0eXBpY2FsbHkgYSBDb3Vyc2UgQXNzZXNzbWVudCBhdCB0aGUgcm9vdCBsZXZlbCBvZiBMZWFybmluZyBQYXRod2F5IChiZWZvcmUgbWlsZXN0b25lcylcbiAgICovXG4gIHByaXZhdGUgY2hlY2tQcmVBc3Nlc3NtZW50Q29tcGxldGlvbigpOiBib29sZWFuIHtcbiAgICAvLyBGaW5kIHRoZSBMZWFybmluZyBQYXRod2F5IHJvb3RcbiAgICBsZXQgbGVhcm5pbmdQYXRod2F5SWQ6IHN0cmluZyB8IG51bGwgPSBudWxsXG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXModGhpcy5oYXNobWFwKSkge1xuICAgICAgY29uc3QgaXRlbSA9IHRoaXMuaGFzaG1hcFtrZXldXG4gICAgICBpZiAoaXRlbS5pc0xlYXJuaW5nUGF0aHdheSAmJiBpdGVtLmNvdXJzZUNhdGVnb3J5ID09PSAnTGVhcm5pbmcgUGF0aHdheScpIHtcbiAgICAgICAgbGVhcm5pbmdQYXRod2F5SWQgPSBrZXlcbiAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zb2xlLmxvZygnQ2hlY2tpbmcgcHJlLWFzc2Vzc21lbnQgY29tcGxldGlvbi4gTGVhcm5pbmcgUGF0aHdheSBJRDonLCBsZWFybmluZ1BhdGh3YXlJZClcblxuICAgIC8vIFBSSU9SSVRZIDE6IExvb2sgZm9yIGl0ZW1zIGV4cGxpY2l0bHkgbWFya2VkIGFzIHByZS1hc3Nlc3NtZW50XG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXModGhpcy5oYXNobWFwKSkge1xuICAgICAgY29uc3QgaXRlbSA9IHRoaXMuaGFzaG1hcFtrZXldXG4gICAgICBpZiAoaXRlbS5pc1ByZUFzc2Vzc21lbnQgPT09IHRydWUpIHtcbiAgICAgICAgLy8gTXVzdCBjaGVjayBmb3IgYWN0dWFsIGNvbXBsZXRpb24gLSBub3QganVzdCBhbnkgdmFsdWVcbiAgICAgICAgY29uc3QgaXNDb21wbGV0ZWQgPSAoaXRlbS5jb21wbGV0aW9uU3RhdHVzID09PSAyIHx8IGl0ZW0uc3RhdHVzID09PSAyIHx8IFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpdGVtLmNvbXBsZXRpb25QZXJjZW50YWdlICE9PSB1bmRlZmluZWQgJiYgaXRlbS5jb21wbGV0aW9uUGVyY2VudGFnZSA+PSAxMDApIHx8IFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpdGVtLnByb2dyZXNzICE9PSB1bmRlZmluZWQgJiYgaXRlbS5wcm9ncmVzcyA+PSAxMDApKVxuICAgICAgICBjb25zb2xlLmxvZyhg4pyFIFByZS1hc3Nlc3NtZW50IGZvdW5kIChpc1ByZUFzc2Vzc21lbnQgZmxhZyk6ICR7a2V5fWAsIHtcbiAgICAgICAgICBuYW1lOiBpdGVtLm5hbWUsXG4gICAgICAgICAgY29tcGxldGlvblN0YXR1czogaXRlbS5jb21wbGV0aW9uU3RhdHVzLFxuICAgICAgICAgIHN0YXR1czogaXRlbS5zdGF0dXMsXG4gICAgICAgICAgY29tcGxldGlvblBlcmNlbnRhZ2U6IGl0ZW0uY29tcGxldGlvblBlcmNlbnRhZ2UsXG4gICAgICAgICAgcHJvZ3Jlc3M6IGl0ZW0ucHJvZ3Jlc3MsXG4gICAgICAgICAgaXNDb21wbGV0ZWQsXG4gICAgICAgICAgLy8gU2hvdyBBTEwgZmllbGRzIHRvIGRlYnVnIHdoYXQncyBhdmFpbGFibGVcbiAgICAgICAgICBhbGxEYXRhOiBKU09OLnN0cmluZ2lmeShpdGVtLCBudWxsLCAyKVxuICAgICAgICB9KVxuICAgICAgICAvLyBQcmUtYXNzZXNzbWVudCBleGlzdHMgLSByZXR1cm4gaXRzIGNvbXBsZXRpb24gc3RhdHVzICh0cnVlL2ZhbHNlKVxuICAgICAgICByZXR1cm4gaXNDb21wbGV0ZWRcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBQUklPUklUWSAyOiBGaW5kIHByZS1hc3Nlc3NtZW50IGluIGhhc2htYXAgLSBkaXJlY3QgY2hpbGQgb2YgTGVhcm5pbmcgUGF0aHdheSB0aGF0IGlzIE5PVCBhIG1pbGVzdG9uZVxuICAgIC8vIENoZWNrIGZvciBmaXJzdCBub24tbWlsZXN0b25lIGNoaWxkIG9mIExlYXJuaW5nIFBhdGh3YXlcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyh0aGlzLmhhc2htYXApKSB7XG4gICAgICBjb25zdCBpdGVtID0gdGhpcy5oYXNobWFwW2tleV1cblxuICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBhIGRpcmVjdCBjaGlsZCBvZiB0aGUgTGVhcm5pbmcgUGF0aHdheVxuICAgICAgaWYgKGl0ZW0ucGFyZW50ICE9PSBsZWFybmluZ1BhdGh3YXlJZCkgY29udGludWVcblxuICAgICAgLy8gU2tpcCBtaWxlc3RvbmVzXG4gICAgICBpZiAoaXRlbS5pc01pbGVzdG9uZSkgY29udGludWVcblxuICAgICAgLy8gVGhpcyBpcyBhIG5vbi1taWxlc3RvbmUgZGlyZWN0IGNoaWxkIC0gaXQncyB0aGUgcHJlLWFzc2Vzc21lbnRcbiAgICAgIC8vIE11c3QgY2hlY2sgZm9yIGFjdHVhbCBjb21wbGV0aW9uIC0gbm90IGp1c3QgYW55IHZhbHVlXG4gICAgICBjb25zdCBpc0NvbXBsZXRlZCA9IChpdGVtLmNvbXBsZXRpb25TdGF0dXMgPT09IDIgfHwgaXRlbS5zdGF0dXMgPT09IDIgfHwgXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChpdGVtLmNvbXBsZXRpb25QZXJjZW50YWdlICE9PSB1bmRlZmluZWQgJiYgaXRlbS5jb21wbGV0aW9uUGVyY2VudGFnZSA+PSAxMDApIHx8IFxuICAgICAgICAgICAgICAgICAgICAgICAgICAoaXRlbS5wcm9ncmVzcyAhPT0gdW5kZWZpbmVkICYmIGl0ZW0ucHJvZ3Jlc3MgPj0gMTAwKSlcbiAgICAgIGNvbnNvbGUubG9nKGDinIUgUHJlLWFzc2Vzc21lbnQgZm91bmQgKGZpcnN0IG5vbi1taWxlc3RvbmUgY2hpbGQpOiAke2tleX1gLCB7XG4gICAgICAgIG5hbWU6IGl0ZW0ubmFtZSxcbiAgICAgICAgY29tcGxldGlvblN0YXR1czogaXRlbS5jb21wbGV0aW9uU3RhdHVzLFxuICAgICAgICBzdGF0dXM6IGl0ZW0uc3RhdHVzLFxuICAgICAgICBjb21wbGV0aW9uUGVyY2VudGFnZTogaXRlbS5jb21wbGV0aW9uUGVyY2VudGFnZSxcbiAgICAgICAgcHJvZ3Jlc3M6IGl0ZW0ucHJvZ3Jlc3MsXG4gICAgICAgIGlzQ29tcGxldGVkLFxuICAgICAgICAvLyBTaG93IEFMTCBmaWVsZHMgdG8gZGVidWcgd2hhdCdzIGF2YWlsYWJsZVxuICAgICAgICBhbGxEYXRhOiBKU09OLnN0cmluZ2lmeShpdGVtLCBudWxsLCAyKVxuICAgICAgfSlcbiAgICAgIC8vIFByZS1hc3Nlc3NtZW50IGV4aXN0cyAtIHJldHVybiBpdHMgY29tcGxldGlvbiBzdGF0dXMgKHRydWUvZmFsc2UpXG4gICAgICByZXR1cm4gaXNDb21wbGV0ZWRcbiAgICB9XG5cbiAgICAvLyBDUklUSUNBTDogSWYgd2UgcmVhY2ggaGVyZSwgbm8gcHJlLWFzc2Vzc21lbnQgd2FzIGZvdW5kIGluIHRoZSBoYXNobWFwXG4gICAgLy8gVGhpcyBjb3VsZCBtZWFuIGVpdGhlcjpcbiAgICAvLyAxLiBUaGVyZSBJUyBubyBwcmUtYXNzZXNzbWVudCAodW5sb2NrIE0xIGJ5IGRlZmF1bHQpXG4gICAgLy8gMi4gVGhlIGhhc2htYXAgaGFzbid0IGJlZW4gcG9wdWxhdGVkIHlldCAoc2hvdWxkIGxvY2sgTTEgdW50aWwgZGF0YSBpcyByZWFkeSlcbiAgICBcbiAgICAvLyBUbyBiZSBzYWZlLCBjaGVjayBpZiBBTlkgY2hpbGRyZW4gZXhpc3QgYXQgYWxsXG4gICAgY29uc3QgaGFzQW55Q2hpbGRyZW4gPSBPYmplY3Qua2V5cyh0aGlzLmhhc2htYXApLnNvbWUoa2V5ID0+IFxuICAgICAgdGhpcy5oYXNobWFwW2tleV0ucGFyZW50ID09PSBsZWFybmluZ1BhdGh3YXlJZFxuICAgIClcbiAgICBcbiAgICBpZiAoIWhhc0FueUNoaWxkcmVuKSB7XG4gICAgICAvLyBIYXNobWFwIG5vdCBwb3B1bGF0ZWQgeWV0IC0gbG9jayBNMSB1bnRpbCBkYXRhIGlzIHJlYWR5XG4gICAgICBjb25zb2xlLmxvZygn4pqg77iPIE5vIGNoaWxkcmVuIGZvdW5kIGluIGhhc2htYXAgeWV0IC0gbG9ja2luZyBNMSB1bnRpbCBkYXRhIGlzIHJlYWR5JylcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgICBcbiAgICAvLyBIYXNobWFwIGlzIHBvcHVsYXRlZCBidXQgbm8gcHJlLWFzc2Vzc21lbnQgZm91bmQgLSBhbGxvdyBNMSB0byB1bmxvY2tcbiAgICBjb25zb2xlLmxvZygnTm8gcHJlLWFzc2Vzc21lbnQgZm91bmQgaW4gZnVsbHkgcG9wdWxhdGVkIGhhc2htYXAgLSBhbGxvd2luZyBNMSB0byBiZSB1bmxvY2tlZCBieSBkZWZhdWx0JylcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGEgbWlsZXN0b25lJ3MgYXNzZXNzbWVudCBpcyBjb21wbGV0ZWRcbiAgICogU2VhcmNoZXMgZm9yIGFueSBhc3Nlc3NtZW50IHR5cGUgKENvdXJzZSBBc3Nlc3NtZW50LCBGaW5hbCBBc3Nlc3NtZW50LCBldGMuKSB0aGF0IGJlbG9uZ3MgdG8gdGhpcyBtaWxlc3RvbmVcbiAgICovXG4gIHByaXZhdGUgY2hlY2tNaWxlc3RvbmVBc3Nlc3NtZW50Q29tcGxldGUobWlsZXN0b25lSWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IG1pbGVzdG9uZSA9IHRoaXMuaGFzaG1hcFttaWxlc3RvbmVJZF1cblxuICAgIC8vIENoZWNrIGFsbCBpdGVtcyBpbiBoYXNobWFwIHRoYXQgYXJlIGFzc2Vzc21lbnRzIGFuZCBiZWxvbmcgdG8gdGhpcyBtaWxlc3RvbmVcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyh0aGlzLmhhc2htYXApKSB7XG4gICAgICBjb25zdCBpdGVtID0gdGhpcy5oYXNobWFwW2tleV1cblxuICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBhbiBhc3Nlc3NtZW50IHR5cGVcbiAgICAgIGNvbnN0IGlzQXNzZXNzbWVudFR5cGUgPVxuICAgICAgICBpdGVtLnByaW1hcnlDYXRlZ29yeSA9PT0gJ0NvdXJzZSBBc3Nlc3NtZW50JyB8fFxuICAgICAgICBpdGVtLnByaW1hcnlDYXRlZ29yeSA9PT0gJ0ZpbmFsIEFzc2Vzc21lbnQnIHx8XG4gICAgICAgIGl0ZW0ucHJpbWFyeUNhdGVnb3J5ID09PSAnUHJhY3RpY2UgUXVlc3Rpb24gU2V0JyB8fFxuICAgICAgICBpdGVtLmNvdXJzZUNhdGVnb3J5ID09PSAnQ291cnNlIEFzc2Vzc21lbnQnIHx8XG4gICAgICAgIGl0ZW0uY291cnNlQ2F0ZWdvcnkgPT09ICdGaW5hbCBBc3Nlc3NtZW50JyB8fFxuICAgICAgICAoaXRlbS5uYW1lICYmIGl0ZW0ubmFtZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKCdhc3Nlc3NtZW50JykpXG5cbiAgICAgIGlmICghaXNBc3Nlc3NtZW50VHlwZSkgY29udGludWVcblxuICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBhc3Nlc3NtZW50IGJlbG9uZ3MgdG8gdGhpcyBtaWxlc3RvbmVcbiAgICAgIGlmICh0aGlzLmlzQ2hpbGRPZk1pbGVzdG9uZShrZXksIG1pbGVzdG9uZUlkKSkge1xuICAgICAgICBjb25zdCBpc0NvbXBsZXRlZCA9IGl0ZW0uY29tcGxldGlvblN0YXR1cyA9PT0gMiB8fCBpdGVtLnN0YXR1cyA9PT0gMiB8fCBpdGVtLmNvbXBsZXRpb25QZXJjZW50YWdlID49IDEwMCB8fCBpdGVtLnByb2dyZXNzID49IDEwMFxuICAgICAgICBpZiAoaXNDb21wbGV0ZWQpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gSWYgbm8gYXNzZXNzbWVudCBmb3VuZCwgY29uc2lkZXIgaXQgYXMgY29tcGxldGVkIChubyBhc3Nlc3NtZW50IHJlcXVpcmVtZW50KVxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgYSBtaWxlc3RvbmUncyBtYW5kYXRvcnkgY29udGVudCBpcyBjb21wbGV0ZWRcbiAgICogT25seSBjaGVja3MgY291cnNlcy9jb250ZW50IHRoYXQgYXJlIG1hcmtlZCBhcyBpc01hbmRhdG9yeVxuICAgKi9cbiAgcHJpdmF0ZSBjaGVja01pbGVzdG9uZU1hbmRhdG9yeUNvbnRlbnRDb21wbGV0ZShtaWxlc3RvbmVJZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgbWlsZXN0b25lID0gdGhpcy5oYXNobWFwW21pbGVzdG9uZUlkXVxuXG4gICAgbGV0IG1hbmRhdG9yeUNvdW50ID0gMFxuICAgIGxldCBjb21wbGV0ZWRNYW5kYXRvcnlDb3VudCA9IDBcblxuICAgIC8vIENoZWNrIGFsbCBpdGVtcyBpbiBoYXNobWFwIHRoYXQgYXJlIGRpcmVjdCBjaGlsZHJlbiBvZiB0aGlzIG1pbGVzdG9uZSAoY291cnNlcylcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyh0aGlzLmhhc2htYXApKSB7XG4gICAgICBjb25zdCBpdGVtID0gdGhpcy5oYXNobWFwW2tleV1cblxuICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpdGVtIGlzIGEgZGlyZWN0IGNoaWxkIG9mIHRoZSBtaWxlc3RvbmUgKGNvdXJzZSBsZXZlbClcbiAgICAgIGlmIChpdGVtLnBhcmVudCAhPT0gbWlsZXN0b25lSWQpIGNvbnRpbnVlXG5cbiAgICAgIC8vIFNraXAgaWYgbm90IGEgY291cnNlIG9yIGNvbGxlY3Rpb25cbiAgICAgIGlmIChpdGVtLnByaW1hcnlDYXRlZ29yeSAhPT0gJ0NvdXJzZScgJiYgIWl0ZW0uaXNDb2xsZWN0aW9uKSBjb250aW51ZVxuXG4gICAgICAvLyBTa2lwIGFzc2Vzc21lbnRzIC0gdGhleSdyZSBjaGVja2VkIHNlcGFyYXRlbHlcbiAgICAgIGNvbnN0IGlzQXNzZXNzbWVudCA9XG4gICAgICAgIGl0ZW0ucHJpbWFyeUNhdGVnb3J5ID09PSAnQ291cnNlIEFzc2Vzc21lbnQnIHx8XG4gICAgICAgIGl0ZW0ucHJpbWFyeUNhdGVnb3J5ID09PSAnRmluYWwgQXNzZXNzbWVudCcgfHxcbiAgICAgICAgaXRlbS5jb3Vyc2VDYXRlZ29yeSA9PT0gJ0NvdXJzZSBBc3Nlc3NtZW50JyB8fFxuICAgICAgICAoaXRlbS5uYW1lICYmIGl0ZW0ubmFtZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKCdhc3Nlc3NtZW50JykpXG4gICAgICBpZiAoaXNBc3Nlc3NtZW50KSBjb250aW51ZVxuXG4gICAgICAvLyBDaGVjayBpZiB0aGlzIGNvbnRlbnQgaXMgbWFuZGF0b3J5XG4gICAgICBpZiAoaXRlbS5pc01hbmRhdG9yeSkge1xuICAgICAgICBtYW5kYXRvcnlDb3VudCsrXG4gICAgICAgIGNvbnN0IGlzQ29tcGxldGVkID0gaXRlbS5jb21wbGV0aW9uU3RhdHVzID09PSAyIHx8IGl0ZW0uc3RhdHVzID09PSAyIHx8IGl0ZW0uY29tcGxldGlvblBlcmNlbnRhZ2UgPj0gMTAwIHx8IGl0ZW0ucHJvZ3Jlc3MgPj0gMTAwXG4gICAgICAgIGlmIChpc0NvbXBsZXRlZCkge1xuICAgICAgICAgIGNvbXBsZXRlZE1hbmRhdG9yeUNvdW50KytcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGFsbENvbXBsZXRlID0gbWFuZGF0b3J5Q291bnQgPT09IDAgfHwgY29tcGxldGVkTWFuZGF0b3J5Q291bnQgPj0gbWFuZGF0b3J5Q291bnRcbiAgICByZXR1cm4gYWxsQ29tcGxldGVcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhIGNvbnRlbnQgaXRlbSBpcyBhIGNoaWxkIChkaXJlY3Qgb3IgbmVzdGVkKSBvZiBhIG1pbGVzdG9uZVxuICAgKi9cbiAgcHJpdmF0ZSBpc0NoaWxkT2ZNaWxlc3RvbmUoY29udGVudElkOiBzdHJpbmcsIG1pbGVzdG9uZUlkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBsZXQgY3VycmVudElkID0gY29udGVudElkXG4gICAgbGV0IGRlcHRoID0gMFxuICAgIGNvbnN0IG1heERlcHRoID0gMTBcblxuICAgIHdoaWxlIChjdXJyZW50SWQgJiYgZGVwdGggPCBtYXhEZXB0aCkge1xuICAgICAgY29uc3QgaXRlbSA9IHRoaXMuaGFzaG1hcFtjdXJyZW50SWRdXG4gICAgICBpZiAoIWl0ZW0pIHJldHVybiBmYWxzZVxuICAgICAgaWYgKGl0ZW0ucGFyZW50ID09PSBtaWxlc3RvbmVJZCkgcmV0dXJuIHRydWVcbiAgICAgIGN1cnJlbnRJZCA9IGl0ZW0ucGFyZW50XG4gICAgICBkZXB0aCsrXG4gICAgfVxuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgZ2V0Q2FsY3VsYXRpb25zRnJvbUNoaWxkcmVuKGl0ZW06IE5zQ29udGVudC5JQ29udGVudCkge1xuICAgIGl0ZW1bJ2R1cmF0aW9uJ10gPSBpdGVtLmNoaWxkcmVuLnJlZHVjZSgoc3VtLCBjaGlsZCkgPT4ge1xuICAgICAgcmV0dXJuIHN1bSArIE51bWJlcihjaGlsZC5kdXJhdGlvbiB8fCAwKVxuICAgIH0sIDApXG4gICAgY29uc3QgY29tcGxldGVkSXRlbXMgPSBfLmZpbHRlcihpdGVtLmNoaWxkcmVuLCByID0+IHIuY29tcGxldGlvblN0YXR1cyA9PT0gMiB8fCByLmNvbXBsZXRpb25QZXJjZW50YWdlID09PSAxMDApXG4gICAgY29uc3QgdG90YWxDb3VudCA9IF8udG9JbnRlZ2VyKF8uZ2V0KGl0ZW0sICdsZWFmTm9kZXNDb3VudCcpKSB8fCAxXG4gICAgaXRlbVsnY29tcGxldGlvblBlcmNlbnRhZ2UnXSA9IE51bWJlcigoKGNvbXBsZXRlZEl0ZW1zLmxlbmd0aCAvIHRvdGFsQ291bnQpICogMTAwKS50b0ZpeGVkKCkpXG4gICAgaXRlbVsnY29tcGxldGlvblN0YXR1cyddID0gKGl0ZW0uY29tcGxldGlvblBlcmNlbnRhZ2UgPj0gMTAwKSA/IDIgOiAxXG4gICAgcmV0dXJuIGl0ZW1cbiAgfVxuXG4gIGZldGNoQ29udGVudEhpc3RvcnlWMihyZXE6IE5zQ29udGVudC5JQ29udGludWVMZWFybmluZ0RhdGFSZXEpOiBPYnNlcnZhYmxlPE5zQ29udGVudC5JQ29udGludWVMZWFybmluZ0RhdGE+IHtcbiAgICByZXEucmVxdWVzdC5maWVsZHMgPSBbJ3Byb2dyZXNzZGV0YWlscyddXG5cbiAgICBpZiAocmVxLnJlcXVlc3QuY291cnNlSWQpIHtcbiAgICAgIGNvbnN0IHJlc2x1dDogYW55ID0gdGhpcy5odHRwLnBvc3Q8TnNDb250ZW50LklDb250aW51ZUxlYXJuaW5nRGF0YT4oXG4gICAgICAgIGAke0FQSV9FTkRfUE9JTlRTLkNPTlRFTlRfSElTVE9SWVYyfS8ke3JlcS5yZXF1ZXN0LmNvdXJzZUlkfWAsIHJlcVxuICAgICAgKVxuICAgICAgLy8gZGF0YS5zdWJzY3JpYmUoKHN1YnNjcmliZURhdGE6IGFueSkgPT4ge1xuICAgICAgLy8gICAgICAgdGhpcy5wcm9ncmFtQ2hpbGRDb3Vyc2VSZXN1bWVEYXRhLm5leHQoeyByZXN1bWVEYXRhOiBzdWJzY3JpYmVEYXRhLnJlc3VsdC5jb250ZW50TGlzdCwgY291cnNlSWQ6IHJlcS5yZXF1ZXN0LmNvdXJzZUlkIH0pXG4gICAgICAvLyAgICAgfSlcbiAgICAgIHJldHVybiByZXNsdXRcbiAgICB9XG4gICAgcmV0dXJuIG9mKClcblxuICB9XG5cbiAgZG93b25sb2FkQ2VydGlmaWNhdGUoY2VydElkOiBhbnkpOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PHsgcmVzdWx0OiBhbnkgfT4oXG4gICAgICBBUElfRU5EX1BPSU5UUy5DRVJUX0RPV05MT0FEKGNlcnRJZCksXG4gICAgKVxuICB9XG4gIGdldFNlcnZlckRhdGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8eyByZXN1bHQ6IE5zQXBwVG9jLklQb3N0QXNzZXNzbWVudFtdIH0+KFxuICAgICAgQVBJX0VORF9QT0lOVFMuU0VSVkVSX0RBVEUpXG4gIH1cblxuICBnZXRGb3JtQnlJZChmb3JtSWQ6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0KEFQSV9FTkRfUE9JTlRTLkdFVF9GT1JNX0JZSUQoZm9ybUlkKSlcbiAgfVxuXG4gIHN1Ym1pdEZvcm0oZm9ybURhdGE6IGFueSkge1xuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdDxhbnk+KEFQSV9FTkRfUE9JTlRTLlNVQk1JVF9GT1JNLCBmb3JtRGF0YSlcbiAgfVxuXG4gIGdldEZvcm1CeUlkUHVibGljKGZvcm1JZDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQoQVBJX0VORF9QT0lOVFMuR0VUX0ZPUk1fQllJRF9QVUJMSUMoZm9ybUlkKSlcbiAgfVxuXG4gIHN1Ym1pdEZvcm1QdWJsaWMoZm9ybURhdGE6IGFueSkge1xuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdDxhbnk+KEFQSV9FTkRfUE9JTlRTLlNVQk1JVF9GT1JNX1BVQkxJQywgZm9ybURhdGEpXG4gIH1cblxuICBnZXRBcGxsaWNhdGlvbnNCeUlkKGZvcm1JZDogc3RyaW5nLCBjb250ZXh0SWQ6IHN0cmluZyk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8YW55PihBUElfRU5EX1BPSU5UUy5HRVRfQVBQTElDQVRJT05TX0JZX0lEKGZvcm1JZCwgY29udGV4dElkKSlcbiAgfVxuXG4gIHNoYXJlQ29udGVudChyZXFCb2R5OiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3Q8YW55PihgJHtBUElfRU5EX1BPSU5UUy5TSEFSRV9DT05URU5UfWAsIHJlcUJvZHkpXG4gIH1cbiAgY2hlY2tNb2R1bGVXaXNlRGF0YShjb250ZW50OiBhbnkpIHtcbiAgICBpZiAoY29udGVudCAmJiBjb250ZW50LmNoaWxkcmVuKSB7XG4gICAgICBjb250ZW50LmNoaWxkcmVuLmZvckVhY2goKGVsZTogYW55KSA9PiB7XG4gICAgICAgIGlmIChlbGUucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5NT0RVTEUpIHtcbiAgICAgICAgICBsZXQgbW9kdWxlUmVzb3Vyc2VDb3VudCA9IDBcbiAgICAgICAgICBsZXQgb2ZmbGluZVJlc291cnNlQ291bnQgPSAwXG4gICAgICAgICAgZWxlLmNoaWxkcmVuLmZvckVhY2goKGNoaWxkRWxlOiBhbnkpID0+IHtcbiAgICAgICAgICAgIGlmIChjaGlsZEVsZS5wcmltYXJ5Q2F0ZWdvcnkgIT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk9GRkxJTkVfU0VTU0lPTikge1xuICAgICAgICAgICAgICBtb2R1bGVSZXNvdXJzZUNvdW50ID0gbW9kdWxlUmVzb3Vyc2VDb3VudCArIDFcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIG9mZmxpbmVSZXNvdXJzZUNvdW50ID0gb2ZmbGluZVJlc291cnNlQ291bnQgKyAxXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSlcbiAgICAgICAgICBlbGVbJ21vZHVsZVJlc291cnNlQ291bnQnXSA9IG1vZHVsZVJlc291cnNlQ291bnRcbiAgICAgICAgICBlbGVbJ29mZmxpbmVSZXNvdXJzZUNvdW50J10gPSBvZmZsaW5lUmVzb3Vyc2VDb3VudFxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChlbGUucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5DT1VSU0UpIHtcbiAgICAgICAgICAgIHRoaXMuY2hlY2tNb2R1bGVXaXNlRGF0YShlbGUpXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cbiAgfVxuICBhc3luYyBmZXRjaENvdXJzZUhlaXJhcmNoeShjb250ZW50RGF0YTogYW55KSB7XG4gICAgaWYgKGNvbnRlbnREYXRhICYmIGNvbnRlbnREYXRhLmNoaWxkcmVuKSB7XG4gICAgICBmb3IgKGNvbnN0IGVsZSBvZiBjb250ZW50RGF0YS5jaGlsZHJlbikge1xuICAgICAgICBpZiAoZWxlLnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVDb3Vyc2VDYXRlZ29yeS5DT1VSU0UpIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLndpZGdldFN2Yy5mZXRjaENvbnRlbnQoZWxlLmlkZW50aWZpZXIpLnRvUHJvbWlzZSgpLnRoZW4oYXN5bmMgKHN1YkVsZTogYW55KSA9PiB7XG4gICAgICAgICAgICBpZiAoc3ViRWxlLnJlc3VsdCAmJiBzdWJFbGUucmVzdWx0LmNvbnRlbnRcbiAgICAgICAgICAgICAgJiYgc3ViRWxlLnJlc3VsdC5jb250ZW50LmNoaWxkcmVuICYmIHN1YkVsZS5yZXN1bHQuY29udGVudC5jaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgZWxlWydjaGlsZHJlbiddID0gc3ViRWxlLnJlc3VsdC5jb250ZW50LmNoaWxkcmVuXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHNldFRyYW5zY3JpcHRpb25EYXRhKGRhdGE6IGFueSkge1xuICAgIC8vICBjb25zb2xlLmxvZygnZGF0YS0tJywgZGF0YSlcbiAgICB0aGlzLnRyYW5zcmlwdGlvbkRhdGFTdWJqZWN0Lm5leHQoZGF0YSk7XG4gIH1cblxuICBzZXRBY3RpdmVTdWJ0aXRsZUxhbmd1YWdlKGFjdGl2ZUxhbmc6IGFueSkge1xuICAgIHRoaXMudHJhbnNyaXB0aW9uQWN0aXZlTGFuZ3VhZ2VEYXRhT2JqZWN0Lm5leHQoYWN0aXZlTGFuZylcbiAgfVxuXG5cblxuICBhaUdldFJlc291cmNlVnR0RmlsZShyZXNvdXJjZUlEOiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5odHRwLmdldDxhbnk+KGAke0FQSV9FTkRfUE9JTlRTLkFJX1JFU09VUkNFX1ZUVF9GSUxFfT9yZXNvdXJjZV9pZD0ke3Jlc291cmNlSUR9YClcbiAgfVxuXG4gIHJlYWRQcmVFbnJvbGxtZW50UmVzb3VyY2VzU3RhdGUocmVxOiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5odHRwXG4gICAgICAucG9zdChgJHtBUElfRU5EX1BPSU5UUy5QUkVfRU5ST0xMTUVOVF9TVEFURV9SRUFEfWAsIHJlcSlcbiAgfVxuXG4gIGNyZWF0ZUNvbnRlbnRWMihyZXF1ZXN0Qm9keTogYW55KSB7XG4gICAgcmV0dXJuIHRoaXMuaHR0cFxuICAgICAgLnBvc3QoXG4gICAgICAgIGAke0FQSV9FTkRfUE9JTlRTLkNSRUFURV9SRVNPVVJDRX1gLFxuICAgICAgICByZXF1ZXN0Qm9keSxcbiAgICAgIClcbiAgICAgIC5waXBlKFxuICAgICAgICBtYXAoKGRhdGE6IGFueSkgPT4ge1xuICAgICAgICAgIHJldHVybiBkYXRhLnJlc3VsdC5pZGVudGlmaWVyXG4gICAgICAgIH0pLFxuICAgICAgKVxuICB9XG5cblxuICB1cGxvYWRBc3NpZ25tZW50QW5zd2VyKGNvbnRlbnRJZDogc3RyaW5nLCBiYXRjaElkOiBzdHJpbmcsIGFzc2lnbm1lbnRJZDogc3RyaW5nLCBmaWxlOiBGaWxlKTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICBjb25zdCBmb3JtRGF0YSA9IG5ldyBGb3JtRGF0YSgpO1xuICAgIGZvcm1EYXRhLmFwcGVuZCgnZmlsZScsIGZpbGUsIGZpbGUubmFtZSlcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3QoYCR7QVBJX0VORF9QT0lOVFMuVVBMT0FEX0FTU0lHTk1FTlR9LyR7Y29udGVudElkfS8ke2JhdGNoSWR9LyR7YXNzaWdubWVudElkfWAsIGZvcm1EYXRhKTtcbiAgfVxuXG5cbiAgcmVhZENvbnRlbnRWMihpZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICByZXR1cm4gdGhpcy5odHRwLmdldDxhbnk+KFxuICAgICAgYCR7QVBJX0VORF9QT0lOVFMuUkVBRF9SRVNPVVJDRX1yZWFkLyR7aWR9P21vZGU9ZWRpdGAsXG4gICAgKS5waXBlKFxuICAgICAgbWFwKChkYXRhOiBhbnkpID0+IHtcbiAgICAgICAgcmV0dXJuIGRhdGEucmVzdWx0LmNvbnRlbnRcbiAgICAgIH0pXG4gICAgKVxuICB9XG5cbiAgdXBsb2FkKFxuICAgIGRhdGE6IEZvcm1EYXRhLFxuICAgIGNvbnRlbnREYXRhOiBhbnksXG4gICAgb3B0aW9ucz86IGFueSxcbiAgKTogT2JzZXJ2YWJsZTxhbnk+IHtcblxuICAgIGNvbnN0IGZpbGUgPSBkYXRhLmdldCgnY29udGVudCcpIGFzIEZpbGVcbiAgICBsZXQgZmlsZU5hbWUgPSBmaWxlLm5hbWVcbiAgICBpZiAoWydjaGFubmVsLmpzb24nXS5pbmRleE9mKGZpbGVOYW1lKSA8IDApIHtcbiAgICAgIGZpbGVOYW1lID0gdGhpcy5hcHBlbmRUb0ZpbGVuYW1lKGZpbGVOYW1lKVxuICAgIH1cbiAgICBjb25zdCBuZXdGb3JtRGF0YSA9IG5ldyBGb3JtRGF0YSgpXG4gICAgbmV3Rm9ybURhdGEuYXBwZW5kKCdkYXRhJywgZmlsZSwgZmlsZU5hbWUpXG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0PGFueT4oXG4gICAgICBgJHtBUElfRU5EX1BPSU5UUy5VUExPQURfRklMRX11cGxvYWQvJHtjb250ZW50RGF0YS5jb250ZW50SWR9YCxcbiAgICAgIG5ld0Zvcm1EYXRhLFxuICAgICAgb3B0aW9uc1xuICAgIClcbiAgfVxuXG4gIGFwcGVuZFRvRmlsZW5hbWUoZmlsZW5hbWU6IHN0cmluZykge1xuICAgIGNvbnN0IHRpbWVTdGFtcCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpXG4gICAgY29uc3QgZG90SW5kZXggPSBmaWxlbmFtZS5sYXN0SW5kZXhPZignLicpXG4gICAgaWYgKGRvdEluZGV4ID09PSAtMSkge1xuICAgICAgcmV0dXJuIGZpbGVuYW1lICsgdGltZVN0YW1wXG4gICAgfVxuICAgIHJldHVybiBmaWxlbmFtZS5zdWJzdHJpbmcoMCwgZG90SW5kZXgpICsgdGltZVN0YW1wICsgZmlsZW5hbWUuc3Vic3RyaW5nKGRvdEluZGV4KVxuICB9XG5cbiAgdXBkYXRlQ29udGVudFdpdGhGZXdGaWVsZHMocmVxdWVzdEJvZHk6IGFueSwgaWRlbnRpZmllcjogc3RyaW5nKTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICByZXR1cm4gdGhpcy5odHRwLnBhdGNoPGFueT4oXG4gICAgICBgJHtBUElfRU5EX1BPSU5UUy5VUERBVEVfUkVTT1VSQ0V9LyR7aWRlbnRpZmllcn1gLFxuICAgICAgcmVxdWVzdEJvZHksXG4gICAgKVxuICB9XG5cbiAgc2VhcmNoQXNzaWdubWVudHMocmVxdWVzdDogYW55KTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3QoQVBJX0VORF9QT0lOVFMuU0VBUkNILCByZXF1ZXN0KVxuICB9XG5cbiAgc3VibWl0RHJhZnRBc3NpZ25tZW50KHJlcXVlc3Q6IGFueSk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wdXQoQVBJX0VORF9QT0lOVFMuU1VCTUlUX0RSQUZUX0FTU0lHTk1FTlQsIHJlcXVlc3QpXG4gIH1cblxuICBzdWJtaXRBc3NpZ25tZW50KHJlcXVlc3Q6IGFueSk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0KEFQSV9FTkRfUE9JTlRTLlNVQk1JVF9BU1NJR05NRU5ULCByZXF1ZXN0KVxuICB9XG5cbiAgbm90aWZ5QXNzaWdubWVudFN1Ym1pc3Npb24ocGF5bG9hZDogYW55KTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3QoQVBJX0VORF9QT0lOVFMuTk9USUZZX0FTU0lHTk1FTlRfU1VCTUlTU0lPTiwgcGF5bG9hZClcbiAgfVxuXG4gIGdldEFzc2lnbm1lbnRTdGF0dXMocmVxdWVzdDogYW55KTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3QoYCR7QVBJX0VORF9QT0lOVFMuQVNTSUdOTUVOVF9TVEFUVVN9YCwgcmVxdWVzdClcbiAgfVxuXG4gIHJlYWRBc3NpZ25tZW50RmlsZShjb250ZW50SWQ6IHN0cmluZywgYmF0Y2hJZDogc3RyaW5nLCBhc3NpZ25tZW50SWQ6IHN0cmluZywgZmlsZU5hbWU6IHN0cmluZyk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgLy8gUHJvcGVybHkgZW5jb2RlIHRoZSBwYXJhbWV0ZXJzIHRvIGF2b2lkIG1hbGZvcm1lZCByZXF1ZXN0IGVycm9yc1xuICAgIGNvbnN0IGVuY29kZWRQYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHtcbiAgICAgIGNvbnRlbnRJZDogY29udGVudElkIHx8ICcnLFxuICAgICAgYmF0Y2hJZDogYmF0Y2hJZCB8fCAnJyxcbiAgICAgIGZvcm1JZDogYXNzaWdubWVudElkIHx8ICcnLFxuICAgICAgZmlsZU5hbWU6IGZpbGVOYW1lIHx8ICcnXG4gICAgfSk7XG5cbiAgICByZXR1cm4gdGhpcy5odHRwLmdldChgJHtBUElfRU5EX1BPSU5UUy5SRUFEX0FTU0lHTk1FTlR9PyR7ZW5jb2RlZFBhcmFtcy50b1N0cmluZygpfWAsIHtcbiAgICAgIHJlc3BvbnNlVHlwZTogJ2Jsb2InLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICAnQWNjZXB0JzogJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSwgYXBwbGljYXRpb24vcGRmLCBhcHBsaWNhdGlvbi9tc3dvcmQsIGFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC53b3JkcHJvY2Vzc2luZ21sLmRvY3VtZW50J1xuICAgICAgfVxuICAgIH0pLnBpcGUoXG4gICAgICBjYXRjaEVycm9yKChlcnJvcjogYW55KSA9PiB7XG4gICAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IGVycm9yKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSBtaWxlc3RvbmUgYWNoaWV2ZW1lbnRcbiAgICogQHBhcmFtIHVzZXJJZCBVc2VyIElEXG4gICAqIEBwYXJhbSBjb3Vyc2VJZCBDb3Vyc2UgaWRlbnRpZmllclxuICAgKiBAcGFyYW0gYmF0Y2hJZCBCYXRjaCBJRFxuICAgKiBAcGFyYW0gbWlsZXN0b25lSWQgTWlsZXN0b25lIGlkZW50aWZpZXIgKGUuZy4sICdtMScsICdtMicpXG4gICAqL1xuICBnZW5lcmF0ZU1pbGVzdG9uZUFjaGlldmVtZW50KHVzZXJJZDogc3RyaW5nLCBjb3Vyc2VJZDogc3RyaW5nLCBiYXRjaElkOiBzdHJpbmcsIG1pbGVzdG9uZUlkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIGNvbnN0IGFwaVVybCA9ICcvYXBpcy9wcm94aWVzL3Y4L2FjaGlldmVtZW50L2R5bmFtaWMvdjEvZ2VuZXJhdGUnXG4gICAgY29uc3QgcmVxdWVzdCA9IHtcbiAgICAgIHJlcXVlc3Q6IHtcbiAgICAgICAgdXNlcklkLFxuICAgICAgICBjb3Vyc2VJZCxcbiAgICAgICAgYmF0Y2hJZCxcbiAgICAgICAgbWlsZXN0b25lSWRcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0KGFwaVVybCwgcmVxdWVzdClcbiAgfVxuXG59XG4iXX0=
1
+ import { Injectable } from '@angular/core';
2
+ import { Subject, EMPTY, BehaviorSubject, of, throwError } from 'rxjs';
3
+ import { NsContent } from '../_services/widget-content.model';
4
+ import { NsContentConstants } from '../_constants/widget-content.constants';
5
+ import { NsAppToc } from '../models/app-toc.model';
6
+ // tslint:disable-next-line
7
+ import _ from 'lodash';
8
+ import { map, catchError } from 'rxjs/operators';
9
+ import * as i0 from "@angular/core";
10
+ import * as i1 from "@angular/common/http";
11
+ import * as i2 from "@sunbird-cb/consumption";
12
+ import * as i3 from "@sunbird-cb/utils-v2";
13
+ import * as i4 from "../_services/widget-content.service";
14
+ // TODO: move this in some common place
15
+ const PROTECTED_SLAG_V8 = '/apis/protected/v8';
16
+ const PROXY_SLAG_V8 = '/apis/proxies/v8';
17
+ const API_END_POINTS = {
18
+ BATCH_CREATE: `${PROXY_SLAG_V8}/learner/course/v1/batch/create`,
19
+ CONTENT_PARENTS: `${PROTECTED_SLAG_V8}/content/parents`,
20
+ CONTENT_NEXT: `${PROTECTED_SLAG_V8}/content/next`,
21
+ CONTENT_HISTORYV2: `/apis/proxies/v8/read/content-progres`,
22
+ CONTENT_PARENT: (contentId) => `${PROTECTED_SLAG_V8}/content/${contentId}/parent`,
23
+ CONTENT_AUTH_PARENT: (contentId, rootOrg, org) => `/apis/authApi/action/content/parent/hierarchy/${contentId}?rootOrg=${rootOrg}&org=${org}`,
24
+ COHORTS: (cohortType, contentId) => `${PROTECTED_SLAG_V8}/cohorts/${cohortType}/${contentId}`,
25
+ EXTERNAL_CONTENT: (contentId) => `${PROTECTED_SLAG_V8}/content/external-access/${contentId}`,
26
+ COHORTS_GROUP_USER: (groupId) => `${PROTECTED_SLAG_V8}/cohorts/${groupId}`,
27
+ RELATED_RESOURCE: (contentId, contentType) => `${PROTECTED_SLAG_V8}/khub/fetchRelatedResources/${contentId}/${contentType}`,
28
+ POST_ASSESSMENT: (contentId) => `${PROTECTED_SLAG_V8}/user/evaluate/post-assessment/${contentId}`,
29
+ GET_CONTENT: (contentId) => `${PROXY_SLAG_V8}/action/content/v3/read/${contentId}`,
30
+ CERT_DOWNLOAD: (certId) => `${PROTECTED_SLAG_V8}/cohorts/course/batch/cert/download/${certId}`,
31
+ SERVER_DATE: 'apis/public/v8/systemDate',
32
+ SHARE_CONTENT: '/apis/proxies/v8/user/v1/content/recommend',
33
+ GET_FORM_BYID: (formId) => `apis/proxies/v8/forms/v2/getFormById?formId=${formId}`,
34
+ // SUBMIT_FORM: `/apis/proxies/v8/forms/v1/saveFormSubmit`,
35
+ SUBMIT_FORM: `apis/proxies/v8/forms/v2/saveFormSubmit`,
36
+ GET_FORM_BYID_PUBLIC: (formId) => `apis/public/v8/public/forms/v2/getFormById?formId=${formId}`,
37
+ SUBMIT_FORM_PUBLIC: `apis/public/v8/public/forms/v2/saveFormSubmit`,
38
+ // get answers for form
39
+ GET_APPLICATIONS_BY_ID: (formId, contextId) => `/apis/proxies/v8/forms/v2/getApplicationsById?formId=${formId}&contextId=${contextId}`,
40
+ AI_RESOURCE_VTT_FILE: `${PROXY_SLAG_V8}/chatbot/v3/transcoder/stats`,
41
+ // GET_FORM_BYID: (formId: string) => `apis/proxies/v8/forms/getFormById?id=${formId}`,
42
+ PRE_ENROLLMENT_STATE_READ: `/apis/proxies/v8/content/v2/state/read`,
43
+ CREATE_RESOURCE: `apis/proxies/v8/action/content/v3/create`,
44
+ READ_RESOURCE: `apis/proxies/v8/action/content/v3/`,
45
+ UPLOAD_FILE: `apis/proxies/v8/upload/action/content/v3/`,
46
+ UPDATE_RESOURCE: `apis/proxies/v8/action/content/v3/update`,
47
+ SEARCH: `apis/proxies/v8/assignment/v1/search`,
48
+ SUBMIT_DRAFT_ASSIGNMENT: `apis/proxies/v8/assignment/v1/submitDraft`,
49
+ SUBMIT_ASSIGNMENT: `apis/proxies/v8/assignment/v1/submit`,
50
+ ASSIGNMENT_STATUS: `apis/proxies/v8/forms/v2/submissions/search`,
51
+ UPLOAD_ASSIGNMENT: `apis/proxies/v8/storage/v1/bp/assignment/answer`,
52
+ READ_ASSIGNMENT: `apis/proxies/v8/storage/v1/bp/assignment/answer/read/file`,
53
+ NOTIFY_ASSIGNMENT_SUBMISSION: `apis/proxies/v8/v1/notifyAssignment/submit`,
54
+ };
55
+ export class AppTocService {
56
+ constructor(http, contentLangSvc, configSvc, widgetSvc) {
57
+ this.http = http;
58
+ this.contentLangSvc = contentLangSvc;
59
+ this.configSvc = configSvc;
60
+ this.widgetSvc = widgetSvc;
61
+ this.analyticsReplaySubject = new Subject();
62
+ this.analyticsFetchStatus = 'none';
63
+ this.batchReplaySubject = new Subject();
64
+ this.setBatchDataSubject = new Subject();
65
+ this.getSelectedBatch = new Subject();
66
+ this.setWFDataSubject = new Subject();
67
+ this.resumeData = new Subject();
68
+ this.showSubtitleOnBanners = false;
69
+ this.canShowDescription = false;
70
+ this.resumeDataSubscription = null;
71
+ this.primaryCategory = NsContent.EPrimaryCategory;
72
+ this.updateReviews = new BehaviorSubject(false);
73
+ this.updateReviewsObservable = this.updateReviews.asObservable();
74
+ this.serverDate = new BehaviorSubject('');
75
+ this.currentServerDate = this.serverDate.asObservable();
76
+ this.contentLoader = new BehaviorSubject(false);
77
+ this.contentLoader$ = this.contentLoader.asObservable();
78
+ this.getPageScroll = new BehaviorSubject(true);
79
+ this.updatePageScroll = this.getPageScroll.asObservable();
80
+ this.hashmap = {};
81
+ this.hashmapUpdated = new BehaviorSubject(null);
82
+ this.hashmapUpdated$ = this.hashmapUpdated.asObservable();
83
+ this.transriptionDataSubject = new BehaviorSubject(null); // Start with null
84
+ this.transcriptionData$ = this.transriptionDataSubject.asObservable();
85
+ this.transriptionActiveLanguageDataObject = new BehaviorSubject(null);
86
+ this.transriptionActiveLanguageDataObject$ = this.transriptionActiveLanguageDataObject.asObservable();
87
+ this.transriptionIdentifier = new Subject(); // Start with null
88
+ this.changeTranscriptionLanguageEvent = new Subject();
89
+ this.playTranscriptionVideo = new Subject();
90
+ // this resume data subscription is for on load
91
+ this.resumeDataSubscription = this.resumeData.subscribe((_dataResult) => {
92
+ });
93
+ }
94
+ get subtitleOnBanners() {
95
+ return this.showSubtitleOnBanners;
96
+ }
97
+ set subtitleOnBanners(val) {
98
+ this.showSubtitleOnBanners = val;
99
+ }
100
+ get showDescription() {
101
+ return this.canShowDescription;
102
+ }
103
+ set showDescription(val) {
104
+ this.canShowDescription = val;
105
+ }
106
+ updateBatchData() {
107
+ this.batchReplaySubject.next();
108
+ }
109
+ setBatchData(data) {
110
+ this.setBatchDataSubject.next(data);
111
+ }
112
+ setWFData(data) {
113
+ this.setWFDataSubject.next(data);
114
+ }
115
+ updateResumaData(data) {
116
+ this.resumeData.next(data);
117
+ }
118
+ changeUpdateReviews(state) {
119
+ this.updateReviews.next(state);
120
+ }
121
+ getSelectedBatchData(data) {
122
+ this.getSelectedBatch.next(data);
123
+ }
124
+ changeServerDate(state) {
125
+ this.serverDate.next(state);
126
+ }
127
+ mapSessionCompletionPercentage(batchData, resumeDataPass) {
128
+ if (resumeDataPass && resumeDataPass.length) {
129
+ if (resumeDataPass && resumeDataPass.length && batchData.content && batchData.content.length) {
130
+ this.sessionCompletionPercentage(batchData, resumeDataPass);
131
+ }
132
+ }
133
+ else {
134
+ this.resumeDataSubscription = this.resumeData.subscribe((dataResult) => {
135
+ if (dataResult && dataResult.length && batchData.content && batchData.content.length) {
136
+ this.sessionCompletionPercentage(batchData, dataResult);
137
+ }
138
+ }, () => {
139
+ this.contentLoader.next(false);
140
+ });
141
+ }
142
+ }
143
+ sessionCompletionPercentage(batchData, resumeDataPass) {
144
+ if (resumeDataPass && resumeDataPass.length) {
145
+ if (batchData && batchData.content[0] &&
146
+ batchData.content[0].batchAttributes &&
147
+ batchData.content[0].batchAttributes.sessionDetails_v2) {
148
+ batchData.content[0].batchAttributes.sessionDetails_v2.map((sd) => {
149
+ const foundContent = resumeDataPass.find((el) => el.contentId === sd.sessionId);
150
+ if (foundContent) {
151
+ sd.completionPercentage = foundContent.completionPercentage;
152
+ sd.completionStatus = foundContent.status;
153
+ sd.lastCompletedTime = foundContent.lastCompletedTime;
154
+ }
155
+ });
156
+ this.contentLoader.next(false);
157
+ }
158
+ }
159
+ }
160
+ showStartButton(content) {
161
+ const status = {
162
+ show: false,
163
+ msg: '',
164
+ };
165
+ if (content) {
166
+ if (content.artifactUrl && content.artifactUrl.match(/youtu(.)?be/gi) &&
167
+ this.configSvc.userProfile &&
168
+ this.configSvc.userProfile.country === 'China') {
169
+ status.show = false;
170
+ status.msg = 'youtubeForbidden';
171
+ return status;
172
+ }
173
+ if (content.resourceType !== 'Certification') {
174
+ status.show = true;
175
+ return status;
176
+ }
177
+ }
178
+ return status;
179
+ }
180
+ initData(data, needResumeData = false) {
181
+ let content = null;
182
+ let errorCode = null;
183
+ this.contentLoader.next(true);
184
+ if (data.content && data.content.data && data.content.data.identifier) {
185
+ content = data.content.data;
186
+ if (needResumeData) {
187
+ this.resumeDataSubscription = this.resumeData.subscribe((dataResult) => {
188
+ if (dataResult && dataResult.length) {
189
+ this.contentLoader.next(true);
190
+ this.mapCompletionPercentage(content, dataResult);
191
+ }
192
+ }, () => {
193
+ // tslint:disable-next-line: no-console
194
+ console.log('error on resumeDataSubscription');
195
+ });
196
+ }
197
+ else {
198
+ this.contentLoader.next(false);
199
+ }
200
+ }
201
+ else {
202
+ this.contentLoader.next(false);
203
+ if (data.error) {
204
+ errorCode = NsAppToc.EWsTocErrorCode.API_FAILURE;
205
+ }
206
+ else {
207
+ errorCode = NsAppToc.EWsTocErrorCode.NO_DATA;
208
+ }
209
+ }
210
+ // this.contentLoader.next(false)
211
+ return {
212
+ content,
213
+ errorCode,
214
+ };
215
+ }
216
+ mapCompletionPercentage(content, dataResult) {
217
+ if (content && content.children) {
218
+ content.children.map(child => {
219
+ const foundContent = dataResult.find((el) => el.contentId === child.identifier);
220
+ if (foundContent) {
221
+ child.completionPercentage = foundContent.completionPercentage || foundContent.progress;
222
+ child.completionStatus = foundContent.status;
223
+ }
224
+ else {
225
+ this.mapCompletionPercentage(child, dataResult);
226
+ }
227
+ });
228
+ this.contentLoader.next(false);
229
+ }
230
+ else {
231
+ this.contentLoader.next(false);
232
+ }
233
+ }
234
+ mapModuleCount(content) {
235
+ if (content && content.children) {
236
+ content.children.map(child => {
237
+ if (child.primaryCategory === NsContent.EPrimaryCategory.MODULE) {
238
+ content['moduleCount'] = content['moduleCount'] ? content['moduleCount'] + 1 : 1;
239
+ }
240
+ if (child.primaryCategory === NsContent.EPrimaryCategory.COURSE) {
241
+ this.mapModuleCount(child);
242
+ }
243
+ });
244
+ }
245
+ }
246
+ getMimeType(content, identifier) {
247
+ if (content.identifier === identifier) {
248
+ return content.mimeType;
249
+ }
250
+ if (content && content.children) {
251
+ if (content.children.length === 0) {
252
+ // if (content.children[0].identifier === identifier) {
253
+ // return content.mimeType
254
+ // }
255
+ // big blunder in data
256
+ // this.logger.log(content.identifier, 'Wrong mimetypes for resume')
257
+ return content.mimeType;
258
+ }
259
+ const flatList = [];
260
+ const getAllItemsPerChildren = (item) => {
261
+ flatList.push(item);
262
+ if (item.children) {
263
+ return item.children.map((i) => getAllItemsPerChildren(i));
264
+ }
265
+ return;
266
+ };
267
+ getAllItemsPerChildren(content);
268
+ const chld = _.first(_.filter(flatList, { identifier }));
269
+ return (chld && chld.mimeType) || '';
270
+ }
271
+ // return chld.mimeType
272
+ return NsContent.EMimeTypes.UNKNOWN;
273
+ }
274
+ getTocStructure(content, tocStructure) {
275
+ if (content &&
276
+ !(content.primaryCategory === this.primaryCategory.RESOURCE
277
+ // || content.primaryCategory === this.primaryCategory.KNOWLEDGE_ARTIFACT)
278
+ || content.primaryCategory === this.primaryCategory.PRACTICE_RESOURCE
279
+ || content.primaryCategory === this.primaryCategory.FINAL_ASSESSMENT
280
+ || content.primaryCategory === this.primaryCategory.OFFLINE_SESSION)) {
281
+ if (content.primaryCategory === NsContent.EPrimaryCategory.COURSE) {
282
+ tocStructure.course += 1;
283
+ }
284
+ else if (content.primaryCategory === NsContent.EPrimaryCategory.MODULE) {
285
+ tocStructure.learningModule += 1;
286
+ }
287
+ _.each(content.children, child => {
288
+ // tslint:disable-next-line: no-parameter-reassignment
289
+ tocStructure = this.getTocStructure(child, tocStructure);
290
+ });
291
+ }
292
+ else if (content &&
293
+ (content.primaryCategory === NsContent.EPrimaryCategory.RESOURCE
294
+ // || content.contentType === 'Knowledge Artifact'
295
+ || content.primaryCategory === NsContent.EPrimaryCategory.PRACTICE_RESOURCE
296
+ || content.primaryCategory === NsContent.EPrimaryCategory.FINAL_ASSESSMENT
297
+ || content.primaryCategory === NsContent.EPrimaryCategory.OFFLINE_SESSION)) {
298
+ switch (content.mimeType) {
299
+ // case NsContent.EMimeTypes.HANDS_ON:
300
+ // tocStructure.handsOn += 1
301
+ // break
302
+ case NsContent.EMimeTypes.MP3:
303
+ tocStructure.podcast += 1;
304
+ break;
305
+ case NsContent.EMimeTypes.MP4:
306
+ case NsContent.EMimeTypes.M3U8:
307
+ case NsContent.EMimeTypes.YOUTUBE:
308
+ tocStructure.video += 1;
309
+ break;
310
+ // case NsContent.EMimeTypes.INTERACTION:
311
+ // tocStructure.interactiveVideo += 1
312
+ // break
313
+ case NsContent.EMimeTypes.PDF:
314
+ tocStructure.pdf += 1;
315
+ break;
316
+ // case NsContent.EMimeTypes.HTML:
317
+ case NsContent.EMimeTypes.TEXT_WEB:
318
+ tocStructure.webPage += 1;
319
+ break;
320
+ case NsContent.EMimeTypes.SURVEY:
321
+ tocStructure.survey += 1;
322
+ break;
323
+ case NsContent.EMimeTypes.QUIZ:
324
+ case NsContent.EMimeTypes.APPLICATION_JSON:
325
+ // if (content.resourceType === 'Assessment') {
326
+ tocStructure.assessment += 1;
327
+ // } else {
328
+ // tocStructure.quiz += 1
329
+ // }
330
+ break;
331
+ case NsContent.EMimeTypes.OFFLINE_SESSION:
332
+ // if (content.resourceType === 'Assessment') {
333
+ tocStructure.offlineSession += 1;
334
+ // } else {
335
+ // tocStructure.quiz += 1
336
+ // }
337
+ break;
338
+ case NsContent.EMimeTypes.PRACTICE_RESOURCE:
339
+ if (content.primaryCategory === this.primaryCategory.PRACTICE_RESOURCE) {
340
+ tocStructure.practiceTest += 1;
341
+ }
342
+ else if (content.primaryCategory === this.primaryCategory.FINAL_ASSESSMENT) {
343
+ tocStructure.finalTest += 1;
344
+ }
345
+ break;
346
+ // case NsContent.EMimeTypes.WEB_MODULE:
347
+ // tocStructure.webModule += 1
348
+ // break
349
+ case NsContent.EMimeTypes.ZIP2:
350
+ case NsContent.EMimeTypes.ZIP:
351
+ tocStructure.interactivecontent += 1;
352
+ break;
353
+ // case NsContent.EMimeTypes.YOUTUBE:
354
+ // tocStructure.youtube += 1
355
+ // break
356
+ default:
357
+ tocStructure.other += 1;
358
+ break;
359
+ }
360
+ return tocStructure;
361
+ }
362
+ return tocStructure;
363
+ }
364
+ filterToc(content, filterCategory = NsContent.EFilterCategory.ALL) {
365
+ if (content.primaryCategory === NsContent.EPrimaryCategory.RESOURCE
366
+ // || content.contentType === 'Knowledge Artifact'
367
+ || content.primaryCategory === NsContent.EPrimaryCategory.PRACTICE_RESOURCE
368
+ || content.primaryCategory === NsContent.EPrimaryCategory.FINAL_ASSESSMENT
369
+ || content.primaryCategory === NsContent.EPrimaryCategory.OFFLINE_SESSION) {
370
+ return this.filterUnitContent(content, filterCategory) ? content : null;
371
+ }
372
+ const filteredChildren = _.map(_.get(content, 'children'), childContent => this.filterToc(childContent, filterCategory))
373
+ .filter(unitContent => Boolean(unitContent));
374
+ if (filteredChildren && filteredChildren.length) {
375
+ return {
376
+ ...content,
377
+ children: filteredChildren,
378
+ };
379
+ }
380
+ return null;
381
+ }
382
+ filterUnitContent(content, filterCategory = NsContent.EFilterCategory.ALL) {
383
+ switch (filterCategory) {
384
+ case NsContent.EFilterCategory.LEARN:
385
+ return (!NsContentConstants.VALID_PRACTICE_RESOURCES.has(content.resourceType) &&
386
+ !NsContentConstants.VALID_ASSESSMENT_RESOURCES.has(content.resourceType));
387
+ case NsContent.EFilterCategory.PRACTICE:
388
+ return NsContentConstants.VALID_PRACTICE_RESOURCES.has(content.resourceType);
389
+ case NsContent.EFilterCategory.ASSESS:
390
+ return NsContentConstants.VALID_ASSESSMENT_RESOURCES.has(content.resourceType);
391
+ case NsContent.EFilterCategory.ALL:
392
+ default:
393
+ return true;
394
+ }
395
+ }
396
+ fetchContentAnalyticsClientData(contentId) {
397
+ if (this.analyticsFetchStatus !== 'fetching' && this.analyticsFetchStatus !== 'done') {
398
+ this.getContentAnalyticsClient(contentId);
399
+ }
400
+ }
401
+ getContentAnalyticsClient(contentId) {
402
+ this.analyticsFetchStatus = 'fetching';
403
+ const url = `${PROXY_SLAG_V8}/LA/api/la/contentanalytics?content_id=${contentId}&type=course`;
404
+ this.http.get(url).subscribe((result) => {
405
+ this.analyticsFetchStatus = 'done';
406
+ this.analyticsReplaySubject.next(result);
407
+ }, () => {
408
+ this.analyticsReplaySubject.next(null);
409
+ this.analyticsFetchStatus = 'done';
410
+ });
411
+ }
412
+ fetchContentAnalyticsData(contentId) {
413
+ if (this.analyticsFetchStatus !== 'fetching' && this.analyticsFetchStatus !== 'done') {
414
+ this.getContentAnalytics(contentId);
415
+ }
416
+ }
417
+ getContentAnalytics(contentId) {
418
+ this.analyticsFetchStatus = 'fetching';
419
+ // tslint:disable-next-line: max-line-length
420
+ const url = `${PROXY_SLAG_V8}/LA/LA/api/Users?refinementfilter=${encodeURIComponent('"source":["iGot","Learning Hub"]')}$${encodeURIComponent(`"courseCode": ["${contentId}"]`)}`;
421
+ this.http.get(url).subscribe((result) => {
422
+ this.analyticsFetchStatus = 'done';
423
+ this.analyticsReplaySubject.next(result);
424
+ }, () => {
425
+ this.analyticsReplaySubject.next(null);
426
+ this.analyticsFetchStatus = 'done';
427
+ });
428
+ }
429
+ clearAnalyticsData() {
430
+ if (this.analyticsReplaySubject) {
431
+ this.analyticsReplaySubject.unsubscribe();
432
+ }
433
+ }
434
+ /**
435
+ * Reset hashmap and related content data
436
+ * Call this when navigating away from content to prevent stale data
437
+ */
438
+ resetContentData() {
439
+ this.hashmap = {};
440
+ this.hashmapUpdated.next(null);
441
+ console.log('Content data cleared - hashmap reset');
442
+ }
443
+ fetchContentParents(contentId) {
444
+ // return this.http.get<NsContent.IContentMinimal[]>(
445
+ // `${API_END_POINTS.CONTENT_PARENTS}/${contentId}`,
446
+ // )
447
+ if (contentId) { }
448
+ return EMPTY;
449
+ }
450
+ fetchContentWhatsNext(contentId, contentType) {
451
+ if (contentType) {
452
+ return this.http.get(`${API_END_POINTS.CONTENT_NEXT}/${contentId}?contentType=${contentType}`);
453
+ }
454
+ return this.http.get(`${API_END_POINTS.CONTENT_NEXT}/${contentId}?ts=${new Date().getTime()}`);
455
+ }
456
+ fetchMoreLikeThisPaid(contentId) {
457
+ return this.http.get(`${API_END_POINTS.CONTENT_NEXT}/${contentId}?exclusiveContent=true&ts=${new Date().getTime()}`);
458
+ }
459
+ fetchMoreLikeThisFree(contentId) {
460
+ return this.http.get(`${API_END_POINTS.CONTENT_NEXT}/${contentId}?exclusiveContent=false&ts=${new Date().getTime()}`);
461
+ }
462
+ fetchContentCohorts(cohortType, contentId) {
463
+ return this.http.get(API_END_POINTS.COHORTS(cohortType, contentId), {
464
+ headers: { rootOrg: this.configSvc.rootOrg || '', org: this.configSvc.org ? this.configSvc.org[0] : '' },
465
+ });
466
+ }
467
+ fetchExternalContentAccess(contentId) {
468
+ return this.http.get(API_END_POINTS.EXTERNAL_CONTENT(contentId));
469
+ }
470
+ fetchCohortGroupUsers(groupId) {
471
+ return this.http.get(API_END_POINTS.COHORTS_GROUP_USER(groupId));
472
+ }
473
+ fetchMoreLikeThis(contentId, contentType) {
474
+ return this.http.get(API_END_POINTS.RELATED_RESOURCE(contentId, contentType));
475
+ }
476
+ fetchPostAssessmentStatus(contentId) {
477
+ return this.http.get(API_END_POINTS.POST_ASSESSMENT(contentId));
478
+ }
479
+ fetchGetContentData(contentId) {
480
+ let url = '';
481
+ const forPreview = window.location.href.includes('/public/') || window.location.href.includes('&preview=true');
482
+ if (!forPreview) {
483
+ return this.http.get(API_END_POINTS.GET_CONTENT(contentId));
484
+ }
485
+ if (window.location.href.includes('editMode=true') && window.location.href.includes('_rc')) {
486
+ url = `/apis/proxies/v8/action/content/v3/read/${contentId}`;
487
+ }
488
+ else {
489
+ url = `/api/content/v1/read/${contentId}`;
490
+ }
491
+ return this.http.get(url);
492
+ }
493
+ fetchContentParent(contentId, data, forPreview = false) {
494
+ return this.http.post(forPreview
495
+ ? API_END_POINTS.CONTENT_AUTH_PARENT(contentId, this.configSvc.rootOrg || '', this.configSvc.org ? this.configSvc.org[0] : '')
496
+ : API_END_POINTS.CONTENT_PARENT(contentId), data);
497
+ }
498
+ createBatch(batchData) {
499
+ return this.http.post(API_END_POINTS.BATCH_CREATE, { request: batchData });
500
+ }
501
+ async mapCompletionPercentageProgram(content, enrolmentList, collectionId) {
502
+ this.contentLoader.next(true);
503
+ let totalCount = 0;
504
+ let leafnodeCount = 0;
505
+ let completedLeafNodes = [];
506
+ let firstUncompleteCourse = '';
507
+ let inprogressDataCheck = [];
508
+ if (content && content.children) {
509
+ leafnodeCount = content.leafNodesCount;
510
+ this.contentLoader.next(true);
511
+ const foundParentContent = this.findEnrolmentByCollectionId(enrolmentList, collectionId || content.identifier);
512
+ if (foundParentContent && foundParentContent.completionPercentage === 100) {
513
+ await this.mapCompletionChildPercentageProgram(content);
514
+ totalCount = content.leafNodesCount;
515
+ }
516
+ else {
517
+ if (content?.primaryCategory !== NsContent.EPrimaryCategory.COURSE) {
518
+ for (let i = 0; i < content.children.length; i += 1) {
519
+ // content.children.forEach(async (parentChild,index) => {
520
+ const parentChild = content.children[i];
521
+ if (parentChild.primaryCategory === NsContent.EPrimaryCategory.COURSE) {
522
+ const foundContent = this.findEnrolmentByCollectionId(enrolmentList, parentChild?.identifier);
523
+ // tslint:disable-next-line: max-line-length
524
+ // totalCount = foundContent && foundContent.completionPercentage ? totalCount + foundContent.completionPercentage : totalCount + 0
525
+ // content.completionPercentage = Math.round(totalCount / leafnodeCount)
526
+ if (foundContent && foundContent.completionPercentage === 100) {
527
+ this.contentLoader.next(true);
528
+ totalCount = totalCount += parentChild.leafNodesCount;
529
+ completedLeafNodes = [...completedLeafNodes, ...parentChild.leafNodes];
530
+ if (foundContent.issuedCertificates.length > 0) {
531
+ const certificate = foundContent.issuedCertificates.sort((a, b) => new Date(a.lastIssuedOn).getTime() - new Date(b.lastIssuedOn).getTime());
532
+ const certId = certificate[0].identifier;
533
+ parentChild.issuedCertificatesId = certId;
534
+ // const certData: any = await this.dowonloadCertificate(certId).toPromise().catch(_error => {
535
+ // this.contentLoader.next(false)
536
+ // })
537
+ // if (certData && certData.result) {
538
+ // parentChild.issuedCertificatesSVG = certData.result.printUri
539
+ // }
540
+ this.contentLoader.next(false);
541
+ }
542
+ parentChild.completionPercentage = 100;
543
+ parentChild.completionStatus = 2;
544
+ await this.mapCompletionChildPercentageProgram(parentChild);
545
+ }
546
+ else {
547
+ if (foundContent) {
548
+ this.contentLoader.next(true);
549
+ const language = this.contentLangSvc.getContentLanguage(parentChild);
550
+ const req = {
551
+ request: {
552
+ batchId: foundContent.batch.batchId,
553
+ userId: foundContent.userId,
554
+ language: language,
555
+ courseId: foundContent.collectionId,
556
+ contentIds: [],
557
+ fields: [
558
+ 'progressdetails',
559
+ ],
560
+ },
561
+ };
562
+ firstUncompleteCourse = (parentChild.completionPercentage === 0 || !parentChild.completionPercentage) &&
563
+ !firstUncompleteCourse ? parentChild : firstUncompleteCourse;
564
+ inprogressDataCheck = inprogressDataCheck;
565
+ await this.fetchContentHistoryV2(req).toPromise().then((progressdata) => {
566
+ const data = progressdata;
567
+ if (data.result && data?.result?.contentList?.length > 0) {
568
+ const completedCount = data.result.contentList.filter((ele) => ele.progress === 100);
569
+ this.checkCompletedLeafnodes(completedLeafNodes, completedCount);
570
+ totalCount = completedLeafNodes.length;
571
+ inprogressDataCheck = [...inprogressDataCheck, ...data.result.contentList];
572
+ // inprogressDataCheck = inprogressDataCheck ? inprogressDataCheck : data.result.contentList
573
+ this.updateResumaData(inprogressDataCheck);
574
+ this.mapCompletionPercentage(parentChild, data.result.contentList);
575
+ this.mapModuleCount(parentChild);
576
+ }
577
+ else {
578
+ this.mapModuleCount(parentChild);
579
+ }
580
+ return progressdata;
581
+ });
582
+ this.contentLoader.next(false);
583
+ }
584
+ }
585
+ }
586
+ // else {
587
+ // if (content.primaryCategory !== NsContent.EPrimaryCategory.BLENDED_PROGRAM) {
588
+ // this.contentLoader.next(true)
589
+ // const foundContent = enrolmentList && enrolmentList.find((el: any) => el.collectionId === content.identifier)
590
+ // if (foundContent) {
591
+ // const req = {
592
+ // request: {
593
+ // batchId: foundContent.batch.batchId,
594
+ // userId: foundContent.userId,
595
+ // courseId: foundContent.collectionId,
596
+ // contentIds: [],
597
+ // fields: [
598
+ // 'progressdetails',
599
+ // ],
600
+ // },
601
+ // }
602
+ // await this.fetchContentHistoryV2(req).toPromise().then((progressdata: any) => {
603
+ // const data: any = progressdata
604
+ // if (data.result && data.result.contentList.length > 0) {
605
+ // const completedCount = data.result.contentList.filter((ele: any) => ele.progress === 100)
606
+ // this.checkCompletedLeafnodes(completedLeafNodes, completedCount)
607
+ // totalCount = completedLeafNodes.length
608
+ // inprogressDataCheck = inprogressDataCheck ? inprogressDataCheck : data.result.contentList
609
+ // this.updateResumaData(inprogressDataCheck)
610
+ // this.mapCompletionPercentage(content, data.result.contentList)
611
+ // }
612
+ // this.contentLoader.next(false)
613
+ // return progressdata
614
+ // })
615
+ // }
616
+ // this.contentLoader.next(false)
617
+ // }
618
+ // }
619
+ this.contentLoader.next(false);
620
+ }
621
+ }
622
+ if (content.primaryCategory === NsContent.EPrimaryCategory.BLENDED_PROGRAM
623
+ || content.primaryCategory === NsContent.EPrimaryCategory.COURSE
624
+ || content.primaryCategory === NsContent.EPrimaryCategory.STANDALONE_ASSESSMENT
625
+ || content.primaryCategory === NsContent.EPrimaryCategory.CURATED_PROGRAM) {
626
+ // this.mapCompletionPercentage(content, this.resumeData)
627
+ const foundParentContent = this.findEnrolmentByCollectionId(enrolmentList, collectionId || content?.identifier);
628
+ const language = this.contentLangSvc.getContentLanguage(content);
629
+ const req = {
630
+ request: {
631
+ batchId: foundParentContent?.batch?.batchId,
632
+ userId: foundParentContent?.userId,
633
+ courseId: foundParentContent?.collectionId,
634
+ language: language,
635
+ contentIds: [],
636
+ fields: [
637
+ 'progressdetails',
638
+ ],
639
+ },
640
+ };
641
+ await this.fetchContentHistoryV2(req).toPromise().then((progressdata) => {
642
+ const data = progressdata;
643
+ if (data && data.result && data.result.contentList.length > 0) {
644
+ const completedCount = data.result.contentList.filter((ele) => ele.progress === 100);
645
+ this.checkCompletedLeafnodes(completedLeafNodes, completedCount);
646
+ totalCount = completedLeafNodes.length;
647
+ inprogressDataCheck = [...inprogressDataCheck, ...data.result.contentList];
648
+ // inprogressDataCheck = inprogressDataCheck ? inprogressDataCheck : data.result.contentList
649
+ this.updateResumaData(inprogressDataCheck);
650
+ this.mapCompletionPercentage(content, data.result.contentList);
651
+ }
652
+ this.contentLoader.next(false);
653
+ return progressdata;
654
+ });
655
+ }
656
+ if (inprogressDataCheck && inprogressDataCheck.length === 0 && firstUncompleteCourse) {
657
+ const firstChildData = this.widgetSvc.getFirstChildInHierarchy(firstUncompleteCourse);
658
+ const childEnrollmentData = enrolmentList.find((el) => el.collectionId === firstUncompleteCourse.identifier);
659
+ const resumeData = [{
660
+ contentId: firstChildData.identifier,
661
+ batchId: childEnrollmentData && childEnrollmentData.batchId,
662
+ completedCount: 1,
663
+ completionPercentage: 0.0,
664
+ progress: 0,
665
+ viewCount: 1,
666
+ courseId: childEnrollmentData && childEnrollmentData.courseId,
667
+ collectionId: childEnrollmentData && childEnrollmentData.courseId,
668
+ status: 1,
669
+ }];
670
+ inprogressDataCheck = resumeData;
671
+ this.updateResumaData(inprogressDataCheck);
672
+ }
673
+ }
674
+ // const parentContent = enrolmentList.find((el: any) => el.collectionId === content.identifier)
675
+ // if (!parentContent.completionPercentage) {
676
+ const calculatedPct = Math.floor((totalCount / leafnodeCount) * 100);
677
+ content.completionPercentage = isNaN(calculatedPct) ? 0 : calculatedPct;
678
+ content.completionStatus = content.completionPercentage >= 100 ? 2 : (content.completionPercentage > 0 ? 1 : 0);
679
+ if (content.completionPercentage === 100 && inprogressDataCheck && inprogressDataCheck.length === 0 && !firstUncompleteCourse) {
680
+ const firstChildData = this.widgetSvc.getFirstChildInHierarchy(content);
681
+ const childEnrollmentData = enrolmentList.find((el) => el.collectionId === content.children[0].identifier);
682
+ const resumeData = [{
683
+ contentId: firstChildData.identifier,
684
+ batchId: childEnrollmentData && childEnrollmentData.batchId,
685
+ completedCount: 1,
686
+ completionPercentage: 100,
687
+ progress: 2,
688
+ viewCount: 1,
689
+ courseId: childEnrollmentData && childEnrollmentData.courseId,
690
+ collectionId: childEnrollmentData && childEnrollmentData.courseId,
691
+ status: 2,
692
+ }];
693
+ inprogressDataCheck = resumeData;
694
+ this.updateResumaData(inprogressDataCheck);
695
+ }
696
+ // // } else {
697
+ // content.completionPercentage = parentContent.completionPercentage
698
+ // // }
699
+ // })
700
+ // this.mapModuleDurationAndProgress(content, content)
701
+ this.callHirarchyProgressHashmap(content);
702
+ this.checkModuleWiseData(content);
703
+ // Compute milestone locking AFTER progress data is populated
704
+ if (content.courseCategory === 'Learning Pathway') {
705
+ this.computeMilestoneLockingStatus();
706
+ // Ensure hashmap updates are published for change detection
707
+ this.hashmap = { ...this.hashmap };
708
+ }
709
+ this.contentLoader.next(false);
710
+ }
711
+ }
712
+ checkCompletedLeafnodes(leafNodes, completedCount) {
713
+ if (completedCount.length > 0) {
714
+ completedCount.forEach((ele) => {
715
+ if (!leafNodes.includes(ele.contentId)) {
716
+ leafNodes.push(ele.contentId);
717
+ }
718
+ });
719
+ }
720
+ }
721
+ // async getProgressForChildCourse(request: any, content: any) {
722
+ // const data: any = await this.fetchContentHistoryV2(request).toPromise().catch(_error => {})
723
+ // if (data.result && data.result.contentList.length > 0) {
724
+ // this.mapCompletionPercentage(content, data.result.contentList)
725
+ // }
726
+ // }
727
+ findEnrolmentByCollectionId(enrolmentList, identifier) {
728
+ return enrolmentList && enrolmentList?.length && enrolmentList.find((el) => el?.collectionId === identifier);
729
+ }
730
+ async mapCompletionChildPercentageProgram(course) {
731
+ if (course && course.children) {
732
+ await course.children.map(async (courseChild) => {
733
+ if ((courseChild && courseChild.children) || courseChild.primaryCategory === NsContent.EPrimaryCategory.MODULE) {
734
+ this.mapCompletionChildPercentageProgram(courseChild);
735
+ course['moduleCount'] = course['moduleCount'] ? course['moduleCount'] + 1 : 1;
736
+ }
737
+ else {
738
+ courseChild['completionPercentage'] = 100;
739
+ courseChild['completionStatus'] = 2;
740
+ }
741
+ });
742
+ }
743
+ }
744
+ mapModuleDurationAndProgress(content, parent) {
745
+ if (content && content.children) {
746
+ if (content.primaryCategory === NsContent.EPrimaryCategory.MODULE) {
747
+ // content.children.map((item: NsContent.IContent)=> {
748
+ /* tslint:disable-next-line */
749
+ content = this.getCalculationsFromChildren(content);
750
+ // })
751
+ }
752
+ content.children.map((item) => {
753
+ // if (item.primaryCategory === NsContent.EPrimaryCategory.MODULE) {
754
+ // this.mapModuleDurationAndProgress(item, parent)
755
+ // } else {
756
+ // this.mapModuleDurationAndProgress(item, parent)
757
+ // }
758
+ if (item && item.children) {
759
+ this.mapModuleDurationAndProgress(item, parent);
760
+ }
761
+ });
762
+ }
763
+ }
764
+ createHirarchyProgressHashmap(hierarchyData, rootCourseCategory) {
765
+ if (hierarchyData && hierarchyData.children) {
766
+ hierarchyData.children.forEach((child) => {
767
+ if (child && child.children) {
768
+ this.createHirarchyProgressHashmap(child, rootCourseCategory);
769
+ }
770
+ const primaryCat = child.primaryCategory;
771
+ const courseCat = (child.courseCategory || child.primaryCategory || '');
772
+ const isMilestone = primaryCat === 'Milestone' || courseCat === 'Milestone';
773
+ const isCollection = child.mimeType === NsContent.EMimeTypes.COLLECTION;
774
+ const isModule = child.primaryCategory === NsContent.EPrimaryCategory.MODULE;
775
+ const isResource = child.primaryCategory === NsContent.EPrimaryCategory.RESOURCE ||
776
+ child.primaryCategory === NsContent.EPrimaryCategory.PRACTICE_RESOURCE ||
777
+ child.primaryCategory === NsContent.EPrimaryCategory.FINAL_ASSESSMENT ||
778
+ child.primaryCategory === NsContent.EPrimaryCategory.COMP_ASSESSMENT;
779
+ const isLearningPathway = rootCourseCategory === 'Learning Pathway';
780
+ // Check if content is mandatory (isMandatory flag or mandatory property)
781
+ const isMandatory = child.isMandatory === true || child.mandatory === true;
782
+ let localMap = {
783
+ parent: child?.parent,
784
+ identifier: child.identifier,
785
+ leafNodesCount: child.leafNodesCount || null,
786
+ leafNodes: child.leafNodes || [],
787
+ completionPercentage: child.completionPercentage || child.progress || 0,
788
+ completionStatus: child.completionStatus || child.status || 0,
789
+ status: child.status || child.completionStatus || 0,
790
+ progress: child.progress,
791
+ primaryCategory: child.primaryCategory,
792
+ courseCategory: courseCat,
793
+ duration: child.duration || 0,
794
+ expectedDuration: child.expectedDuration || 0,
795
+ // Additional metadata for performance optimization
796
+ mimeType: child.mimeType,
797
+ isLocked: child.isLocked || false,
798
+ artifactUrl: child.artifactUrl || null,
799
+ name: child.name || '',
800
+ contentType: child.contentType || '',
801
+ // Pre-computed flags for Learning Pathway
802
+ isMilestone: isMilestone,
803
+ isCollection: isCollection,
804
+ isModule: isModule,
805
+ isResource: isResource,
806
+ isLearningPathway: isLearningPathway,
807
+ isMandatory: isMandatory,
808
+ // Milestone specific data
809
+ milestoneIndex: child.milestoneIndex,
810
+ completedLeafNodesCount: child.completedLeafNodesCount || 0,
811
+ // Pre-assessment flag (for milestone gating)
812
+ isPreAssessment: child.isPreAssessment || false,
813
+ };
814
+ // Debug logging for milestones
815
+ if (isMilestone) {
816
+ // Progress tracked for milestone
817
+ }
818
+ this.hashmap[child.identifier] = localMap;
819
+ });
820
+ }
821
+ }
822
+ createPreAssessmentHirarchyProgressHashmap(hierarchyData) {
823
+ if (hierarchyData && hierarchyData.preEnrolmentResources) {
824
+ hierarchyData.preEnrolmentResources.forEach((child) => {
825
+ if (child && child.preEnrolmentResources) {
826
+ this.createPreAssessmentHirarchyProgressHashmap(child);
827
+ }
828
+ let localMap = {};
829
+ localMap = {
830
+ parent: child?.parent,
831
+ identifier: child.identifier,
832
+ leafNodesCount: child.leafNodesCount || null,
833
+ leafNodes: child.leafNodes || [],
834
+ completionPercentage: child.completionPercentage || child.progress,
835
+ completionStatus: child.completionStatus,
836
+ status: child.status || child.completionStatus || 0,
837
+ progress: child.progress,
838
+ primaryCategory: child.primaryCategory,
839
+ courseCategory: child.courseCategory || child.primaryCategory || '',
840
+ duration: child.duration || 0,
841
+ expectedDuration: child.expectedDuration || 0,
842
+ // Mark as pre-assessment ONLY if explicitly set - do NOT default to true
843
+ isPreAssessment: child.isPreAssessment || false,
844
+ };
845
+ this.hashmap[child.identifier] = localMap;
846
+ });
847
+ }
848
+ }
849
+ callHirarchyProgressHashmap(hierarchyData) {
850
+ if (hierarchyData) {
851
+ const rootCourseCategory = hierarchyData.courseCategory || hierarchyData.primaryCategory || '';
852
+ const isLearningPathway = rootCourseCategory === 'Learning Pathway';
853
+ this.hashmap[hierarchyData.identifier] = {
854
+ parent: hierarchyData.parent,
855
+ identifier: hierarchyData.identifier,
856
+ leafNodesCount: hierarchyData.leafNodesCount || null,
857
+ leafNodes: hierarchyData.leafNodes || [],
858
+ completionPercentage: hierarchyData.completionPercentage || hierarchyData.progress || 0,
859
+ completionStatus: hierarchyData.completionStatus || 0,
860
+ progress: hierarchyData.progress,
861
+ primaryCategory: hierarchyData.primaryCategory,
862
+ courseCategory: rootCourseCategory,
863
+ expectedDuration: hierarchyData.expectedDuration || 0,
864
+ // Additional metadata
865
+ mimeType: hierarchyData.mimeType,
866
+ isLocked: hierarchyData.isLocked || false,
867
+ artifactUrl: hierarchyData.artifactUrl || null,
868
+ name: hierarchyData.name || '',
869
+ contentType: hierarchyData.contentType || '',
870
+ isMilestone: false,
871
+ isCollection: hierarchyData.mimeType === NsContent.EMimeTypes.COLLECTION,
872
+ isModule: hierarchyData.primaryCategory === NsContent.EPrimaryCategory.MODULE,
873
+ isResource: false,
874
+ isLearningPathway: isLearningPathway,
875
+ };
876
+ if (hierarchyData.primaryCategory === NsContent.EPrimaryCategory.CURATED_PROGRAM &&
877
+ hierarchyData.compatibilityLevel >= 5 && hierarchyData.contextLockingType &&
878
+ hierarchyData.contextLockingType === NsContent.EContextLockingType.COURSE_ASSESSMENT_ONLY) {
879
+ this.hashmap[hierarchyData.identifier] = {
880
+ ...this.hashmap[hierarchyData.identifier],
881
+ contextLockingType: hierarchyData.contextLockingType,
882
+ compatibilityLevel: hierarchyData.compatibilityLevel,
883
+ };
884
+ }
885
+ this.createHirarchyProgressHashmap(hierarchyData, rootCourseCategory);
886
+ // NOTE: computeMilestoneLockingStatus is called AFTER progress data is populated
887
+ // in mapCompletionPercentageProgram, not here where completion data is still 0
888
+ this.hashmap = { ...this.hashmap };
889
+ }
890
+ }
891
+ /**
892
+ * Pre-compute milestone locking status for all milestones in Learning Pathway
893
+ * This avoids expensive calculations in component getters
894
+ *
895
+ * Locking Rules:
896
+ * 0. If user is not enrolled, ALL milestones are locked
897
+ * 1. All milestones are locked by default
898
+ * 2. Milestone 1 (M1) unlocks when pre-assessment is completed
899
+ * 3. Milestone N (N > 1) unlocks when:
900
+ * - All mandatory learning items in Milestone N-1 are completed
901
+ * - The assessment of Milestone N-1 is completed
902
+ */
903
+ /**
904
+ * ═══════════════════════════════════════════════════════════════════════════
905
+ * LEARNING PATHWAY MILESTONE LOCKING SYSTEM - SINGLE SOURCE OF TRUTH
906
+ * ═══════════════════════════════════════════════════════════════════════════
907
+ *
908
+ * This method is the SINGLE SOURCE OF TRUTH for all milestone and assessment locking.
909
+ * All locking logic is computed here and stored in the hashmap.
910
+ * Components READ ONLY from the hashmap - they do NOT compute locks themselves.
911
+ *
912
+ * LOCKING RULES:
913
+ * ───────────────────────────────────────────────────────────────────────────
914
+ * 1. DEFAULT STATE: All milestones are LOCKED by default
915
+ *
916
+ * 2. MILESTONE 1 UNLOCKING:
917
+ * - Unlocks when: Pre-assessment is 100% complete
918
+ * - Lock message: "Complete the preliminary assessment to unlock this milestone"
919
+ *
920
+ * 3. MILESTONE N (N >= 2) UNLOCKING:
921
+ * - Unlocks when: Previous milestone is 100% complete
922
+ * - Previous milestone is complete when:
923
+ * a) All MANDATORY courses are 100% complete
924
+ * b) Milestone assessment is 100% complete
925
+ * - Lock message: "Complete all mandatory content and assessment in Milestone N-1"
926
+ *
927
+ * 4. ASSESSMENT LOCKING (within unlocked milestones):
928
+ * - Assessment locked until: All MANDATORY courses in SAME milestone complete
929
+ * - Optional courses do NOT affect assessment locking
930
+ * - Assessment lock message: "Complete all mandatory items to unlock the assessment"
931
+ * - Once assessment is completed, it stays unlocked
932
+ *
933
+ * 5. PARENT MILESTONE LOCKING:
934
+ * - All content inside locked milestone gets isParentMilestoneLocked = true
935
+ * - This includes courses, assessments, nested resources
936
+ *
937
+ * 6. MANDATORY vs OPTIONAL:
938
+ * - By default, ALL courses are mandatory (unless isMandatory: false)
939
+ * - Optional courses do NOT block progression
940
+ *
941
+ * ═══════════════════════════════════════════════════════════════════════════
942
+ */
943
+ computeMilestoneLockingStatus(isEnrolled = true) {
944
+ if (!this.hashmap || Object.keys(this.hashmap).length === 0) {
945
+ console.warn('⚠️ Hashmap is empty - cannot compute milestone locking');
946
+ return;
947
+ }
948
+ console.log('\n═══════════════════════════════════════════════════════════');
949
+ console.log('🔒 MILESTONE LOCKING COMPUTATION START');
950
+ console.log('═══════════════════════════════════════════════════════════');
951
+ console.log('User enrolled:', isEnrolled);
952
+ console.log('Hashmap size:', Object.keys(this.hashmap).length);
953
+ // STEP 1: Find all milestones and sort by index
954
+ const milestoneEntries = Object.keys(this.hashmap)
955
+ .filter(key => {
956
+ const item = this.hashmap[key];
957
+ return item.isMilestone || item.primaryCategory === 'Milestone' || item.courseCategory === 'Milestone';
958
+ })
959
+ .sort((a, b) => {
960
+ const itemA = this.hashmap[a];
961
+ const itemB = this.hashmap[b];
962
+ if (itemA.milestoneIndex !== undefined && itemB.milestoneIndex !== undefined) {
963
+ return itemA.milestoneIndex - itemB.milestoneIndex;
964
+ }
965
+ const numA = parseInt(a.replace(/\D/g, '')) || 0;
966
+ const numB = parseInt(b.replace(/\D/g, '')) || 0;
967
+ return numA - numB;
968
+ });
969
+ if (milestoneEntries.length === 0) {
970
+ console.log('ℹ️ No milestones found - skipping milestone locking');
971
+ console.log('═══════════════════════════════════════════════════════════\n');
972
+ return;
973
+ }
974
+ console.log(`\n📍 Found ${milestoneEntries.length} milestones:`);
975
+ milestoneEntries.forEach((id, i) => {
976
+ console.log(` M${i + 1}: ${this.hashmap[id].name || id}`);
977
+ });
978
+ // STEP 2: If user NOT enrolled, lock ALL milestones and children
979
+ if (!isEnrolled) {
980
+ console.log('\n⚠️ User NOT enrolled - locking ALL milestones and children');
981
+ milestoneEntries.forEach(milestoneId => {
982
+ this.hashmap[milestoneId].computedIsLocked = true;
983
+ this.hashmap[milestoneId].unlockMessage = 'Enroll in this course to access milestones';
984
+ });
985
+ // Lock all children
986
+ Object.keys(this.hashmap).forEach(key => {
987
+ if (!this.hashmap[key].isMilestone) {
988
+ this.hashmap[key].isParentMilestoneLocked = true;
989
+ }
990
+ });
991
+ this.hashmap = { ...this.hashmap };
992
+ this.hashmapUpdated.next({ timestamp: Date.now(), hashmap: this.hashmap });
993
+ console.log('═══════════════════════════════════════════════════════════\n');
994
+ return;
995
+ }
996
+ // STEP 3: Check pre-assessment completion
997
+ const isPreAssessmentCompleted = this.checkPreAssessmentCompletion();
998
+ console.log(`\n📝 Pre-assessment: ${isPreAssessmentCompleted ? '✅ COMPLETE' : '❌ INCOMPLETE'}`);
999
+ // STEP 4: Compute locking for each milestone
1000
+ console.log('\n🔐 Computing milestone locks:');
1001
+ console.log('─────────────────────────────────────────────────────────────');
1002
+ milestoneEntries.forEach((milestoneId, index) => {
1003
+ const milestone = this.hashmap[milestoneId];
1004
+ if (!milestone)
1005
+ return;
1006
+ const milestoneNum = index + 1;
1007
+ console.log(`\n📌 Milestone ${milestoneNum} (${milestone.name || milestoneId}):`);
1008
+ // MILESTONE 1: Unlocks when pre-assessment complete
1009
+ if (index === 0) {
1010
+ const isLocked = !isPreAssessmentCompleted;
1011
+ this.hashmap[milestoneId].computedIsLocked = isLocked;
1012
+ this.hashmap[milestoneId].unlockMessage = isLocked ?
1013
+ 'Complete the preliminary assessment to unlock this milestone' : '';
1014
+ console.log(` ${isLocked ? '🔒 LOCKED' : '🔓 UNLOCKED'}`);
1015
+ console.log(` Reason: Pre-assessment ${isPreAssessmentCompleted ? 'complete' : 'incomplete'}`);
1016
+ // For unlocked M1, check assessment locking
1017
+ if (!isLocked) {
1018
+ console.log(` ✓ Checking assessment lock...`);
1019
+ this.computeAssessmentLockingInMilestone(milestoneId);
1020
+ }
1021
+ else {
1022
+ console.log(` ⨯ Milestone locked - marking all children as parent-locked`);
1023
+ this.markMilestoneChildrenAsParentLocked(milestoneId, true);
1024
+ }
1025
+ return;
1026
+ }
1027
+ // MILESTONE N (N > 1): Unlocks when previous milestone complete
1028
+ const previousMilestoneId = milestoneEntries[index - 1];
1029
+ const previousMilestone = this.hashmap[previousMilestoneId];
1030
+ if (previousMilestone) {
1031
+ // Check completion via multiple strategies
1032
+ const prevCompletionPct = Number(previousMilestone.completionPercentage) || 0;
1033
+ const prevCompletionStatus = Number(previousMilestone.completionStatus) || 0;
1034
+ const prevStatus = Number(previousMilestone.status) || 0;
1035
+ const prevCompletedLeafNodes = Number(previousMilestone.completedLeafNodesCount) || 0;
1036
+ const prevLeafNodesCount = Number(previousMilestone.leafNodesCount) || 0;
1037
+ let previousMilestoneComplete = prevCompletionPct >= 100 ||
1038
+ prevCompletionStatus === 2 ||
1039
+ prevStatus === 2 ||
1040
+ (prevLeafNodesCount > 0 && prevCompletedLeafNodes >= prevLeafNodesCount);
1041
+ // Fallback: Check individual items
1042
+ if (!previousMilestoneComplete) {
1043
+ const isPreviousMilestoneAssessmentComplete = this.checkMilestoneAssessmentComplete(previousMilestoneId);
1044
+ const isPreviousMilestoneMandatoryComplete = this.checkMilestoneMandatoryContentComplete(previousMilestoneId);
1045
+ previousMilestoneComplete = isPreviousMilestoneAssessmentComplete && isPreviousMilestoneMandatoryComplete;
1046
+ console.log(` Fallback check: mandatory=${isPreviousMilestoneMandatoryComplete}, assessment=${isPreviousMilestoneAssessmentComplete}`);
1047
+ }
1048
+ const isLocked = !previousMilestoneComplete;
1049
+ this.hashmap[milestoneId].computedIsLocked = isLocked;
1050
+ this.hashmap[milestoneId].unlockMessage = isLocked ?
1051
+ `Complete all mandatory content and assessment in Milestone ${index} to unlock this milestone` : '';
1052
+ console.log(` ${isLocked ? '🔒 LOCKED' : '🔓 UNLOCKED'}`);
1053
+ console.log(` Reason: Previous milestone ${previousMilestoneComplete ? 'complete' : 'incomplete'}`);
1054
+ console.log(` Previous M${index} progress: ${prevCompletionPct}%`);
1055
+ // For unlocked milestones, check assessment locking
1056
+ if (!isLocked) {
1057
+ console.log(` ✓ Checking assessment lock...`);
1058
+ this.computeAssessmentLockingInMilestone(milestoneId);
1059
+ }
1060
+ else {
1061
+ console.log(` ⨯ Milestone locked - marking all children as parent-locked`);
1062
+ this.markMilestoneChildrenAsParentLocked(milestoneId, true);
1063
+ }
1064
+ }
1065
+ else {
1066
+ this.hashmap[milestoneId].computedIsLocked = true;
1067
+ this.hashmap[milestoneId].unlockMessage = 'Previous milestone not found';
1068
+ console.log(` 🔒 LOCKED (previous milestone not found)`);
1069
+ }
1070
+ });
1071
+ // STEP 5: Compute parent milestone lock status for ALL children
1072
+ console.log('\n🔗 Computing parent milestone locks for all children...');
1073
+ Object.keys(this.hashmap).forEach(key => {
1074
+ const item = this.hashmap[key];
1075
+ if (item.isMilestone)
1076
+ return; // Skip milestones themselves
1077
+ // Traverse up to find if any ancestor milestone is locked
1078
+ let currentParentId = item.parent;
1079
+ let depth = 0;
1080
+ const maxDepth = 5;
1081
+ let foundLockedParent = false;
1082
+ while (currentParentId && depth < maxDepth) {
1083
+ const parentData = this.hashmap[currentParentId];
1084
+ if (parentData) {
1085
+ if (parentData.isMilestone && parentData.computedIsLocked) {
1086
+ this.hashmap[key].isParentMilestoneLocked = true;
1087
+ foundLockedParent = true;
1088
+ break;
1089
+ }
1090
+ currentParentId = parentData.parent;
1091
+ }
1092
+ else {
1093
+ break;
1094
+ }
1095
+ depth++;
1096
+ }
1097
+ if (!foundLockedParent) {
1098
+ this.hashmap[key].isParentMilestoneLocked = false;
1099
+ }
1100
+ });
1101
+ // STEP 6: Trigger hashmap update
1102
+ console.log('\n─────────────────────────────────────────────────────────────');
1103
+ console.log('✅ Milestone locking computation COMPLETE');
1104
+ console.log('═══════════════════════════════════════════════════════════\n');
1105
+ this.hashmap = { ...this.hashmap };
1106
+ this.hashmapUpdated.next({ timestamp: Date.now(), hashmap: this.hashmap });
1107
+ }
1108
+ /**
1109
+ * Trigger milestone lock update when hashmap progress is updated externally
1110
+ * Called from viewer-util.service.ts after progress updates
1111
+ */
1112
+ triggerMilestoneLockUpdate() {
1113
+ // Check if we have a Learning Pathway in the hashmap
1114
+ const hasLearningPathway = Object.keys(this.hashmap).some(key => {
1115
+ const item = this.hashmap[key];
1116
+ return item.isLearningPathway && item.courseCategory === 'Learning Pathway';
1117
+ });
1118
+ if (hasLearningPathway) {
1119
+ console.log('🔄 Triggering milestone lock recomputation after progress update');
1120
+ // Assume enrolled since progress was just updated
1121
+ this.computeMilestoneLockingStatus(true);
1122
+ }
1123
+ }
1124
+ /**
1125
+ * Check if pre-assessment (preliminary assessment) is completed
1126
+ * Pre-assessment is typically a Course Assessment at the root level of Learning Pathway (before milestones)
1127
+ */
1128
+ checkPreAssessmentCompletion() {
1129
+ // Find the Learning Pathway root
1130
+ let learningPathwayId = null;
1131
+ for (const key of Object.keys(this.hashmap)) {
1132
+ const item = this.hashmap[key];
1133
+ if (item.isLearningPathway && item.courseCategory === 'Learning Pathway') {
1134
+ learningPathwayId = key;
1135
+ break;
1136
+ }
1137
+ }
1138
+ console.log('Checking pre-assessment completion. Learning Pathway ID:', learningPathwayId);
1139
+ // PRIORITY 1: Look for items explicitly marked as pre-assessment
1140
+ for (const key of Object.keys(this.hashmap)) {
1141
+ const item = this.hashmap[key];
1142
+ if (item.isPreAssessment === true) {
1143
+ // Must check for actual completion - not just any value
1144
+ const isCompleted = (item.completionStatus === 2 || item.status === 2 ||
1145
+ (item.completionPercentage !== undefined && item.completionPercentage >= 100) ||
1146
+ (item.progress !== undefined && item.progress >= 100));
1147
+ console.log(`✅ Pre-assessment found (isPreAssessment flag): ${key}`, {
1148
+ name: item.name,
1149
+ completionStatus: item.completionStatus,
1150
+ status: item.status,
1151
+ completionPercentage: item.completionPercentage,
1152
+ progress: item.progress,
1153
+ isCompleted,
1154
+ // Show ALL fields to debug what's available
1155
+ allData: JSON.stringify(item, null, 2)
1156
+ });
1157
+ // Pre-assessment exists - return its completion status (true/false)
1158
+ return isCompleted;
1159
+ }
1160
+ }
1161
+ // PRIORITY 2: Find pre-assessment in hashmap - direct child of Learning Pathway that is NOT a milestone
1162
+ // Check for first non-milestone child of Learning Pathway
1163
+ for (const key of Object.keys(this.hashmap)) {
1164
+ const item = this.hashmap[key];
1165
+ // Check if this is a direct child of the Learning Pathway
1166
+ if (item.parent !== learningPathwayId)
1167
+ continue;
1168
+ // Skip milestones
1169
+ if (item.isMilestone)
1170
+ continue;
1171
+ // This is a non-milestone direct child - it's the pre-assessment
1172
+ // Must check for actual completion - not just any value
1173
+ const isCompleted = (item.completionStatus === 2 || item.status === 2 ||
1174
+ (item.completionPercentage !== undefined && item.completionPercentage >= 100) ||
1175
+ (item.progress !== undefined && item.progress >= 100));
1176
+ console.log(`✅ Pre-assessment found (first non-milestone child): ${key}`, {
1177
+ name: item.name,
1178
+ completionStatus: item.completionStatus,
1179
+ status: item.status,
1180
+ completionPercentage: item.completionPercentage,
1181
+ progress: item.progress,
1182
+ isCompleted,
1183
+ // Show ALL fields to debug what's available
1184
+ allData: JSON.stringify(item, null, 2)
1185
+ });
1186
+ // Pre-assessment exists - return its completion status (true/false)
1187
+ return isCompleted;
1188
+ }
1189
+ // CRITICAL: If we reach here, no pre-assessment was found in the hashmap
1190
+ // This could mean either:
1191
+ // 1. There IS no pre-assessment (unlock M1 by default)
1192
+ // 2. The hashmap hasn't been populated yet (should lock M1 until data is ready)
1193
+ // To be safe, check if ANY children exist at all
1194
+ const hasAnyChildren = Object.keys(this.hashmap).some(key => this.hashmap[key].parent === learningPathwayId);
1195
+ if (!hasAnyChildren) {
1196
+ // Hashmap not populated yet - lock M1 until data is ready
1197
+ console.log('⚠️ No children found in hashmap yet - locking M1 until data is ready');
1198
+ return false;
1199
+ }
1200
+ // Hashmap is populated but no pre-assessment found - allow M1 to unlock
1201
+ console.log('No pre-assessment found in fully populated hashmap - allowing M1 to be unlocked by default');
1202
+ return true;
1203
+ }
1204
+ /**
1205
+ * Check if a milestone's assessment is completed
1206
+ * Searches for any assessment type (Course Assessment, Final Assessment, etc.) that belongs to this milestone
1207
+ */
1208
+ checkMilestoneAssessmentComplete(milestoneId) {
1209
+ const milestone = this.hashmap[milestoneId];
1210
+ // Check all items in hashmap that are assessments and belong to this milestone
1211
+ for (const key of Object.keys(this.hashmap)) {
1212
+ const item = this.hashmap[key];
1213
+ // Check if this is an assessment type
1214
+ const isAssessmentType = item.primaryCategory === 'Course Assessment' ||
1215
+ item.primaryCategory === 'Final Assessment' ||
1216
+ item.primaryCategory === 'Practice Question Set' ||
1217
+ item.courseCategory === 'Course Assessment' ||
1218
+ item.courseCategory === 'Final Assessment' ||
1219
+ (item.name && item.name.toLowerCase().includes('assessment'));
1220
+ if (!isAssessmentType)
1221
+ continue;
1222
+ // Check if this assessment belongs to this milestone
1223
+ if (this.isChildOfMilestone(key, milestoneId)) {
1224
+ const isCompleted = item.completionStatus === 2 || item.status === 2 || item.completionPercentage >= 100 || item.progress >= 100;
1225
+ if (isCompleted) {
1226
+ return true;
1227
+ }
1228
+ }
1229
+ }
1230
+ // If no assessment found, consider it as completed (no assessment requirement)
1231
+ return true;
1232
+ }
1233
+ /**
1234
+ * Check if a milestone's mandatory content is completed
1235
+ * Only checks courses/content that are marked as isMandatory
1236
+ */
1237
+ checkMilestoneMandatoryContentComplete(milestoneId) {
1238
+ const milestone = this.hashmap[milestoneId];
1239
+ let mandatoryCount = 0;
1240
+ let completedMandatoryCount = 0;
1241
+ // Check all items in hashmap that are direct children of this milestone (courses)
1242
+ for (const key of Object.keys(this.hashmap)) {
1243
+ const item = this.hashmap[key];
1244
+ // Check if this item is a direct child of the milestone (course level)
1245
+ if (item.parent !== milestoneId)
1246
+ continue;
1247
+ // Skip if not a course or collection
1248
+ if (item.primaryCategory !== 'Course' && !item.isCollection)
1249
+ continue;
1250
+ // Skip assessments - they're checked separately
1251
+ const isAssessment = item.primaryCategory === 'Course Assessment' ||
1252
+ item.primaryCategory === 'Final Assessment' ||
1253
+ item.courseCategory === 'Course Assessment' ||
1254
+ (item.name && item.name.toLowerCase().includes('assessment'));
1255
+ if (isAssessment)
1256
+ continue;
1257
+ // Check if this content is mandatory
1258
+ if (item.isMandatory) {
1259
+ mandatoryCount++;
1260
+ const isCompleted = item.completionStatus === 2 || item.status === 2 || item.completionPercentage >= 100 || item.progress >= 100;
1261
+ if (isCompleted) {
1262
+ completedMandatoryCount++;
1263
+ }
1264
+ }
1265
+ }
1266
+ const allComplete = mandatoryCount === 0 || completedMandatoryCount >= mandatoryCount;
1267
+ return allComplete;
1268
+ }
1269
+ /**
1270
+ * Check if a content item is a child (direct or nested) of a milestone
1271
+ */
1272
+ isChildOfMilestone(contentId, milestoneId) {
1273
+ let currentId = contentId;
1274
+ let depth = 0;
1275
+ const maxDepth = 10;
1276
+ while (currentId && depth < maxDepth) {
1277
+ const item = this.hashmap[currentId];
1278
+ if (!item)
1279
+ return false;
1280
+ if (item.parent === milestoneId)
1281
+ return true;
1282
+ currentId = item.parent;
1283
+ depth++;
1284
+ }
1285
+ return false;
1286
+ }
1287
+ /**
1288
+ * Compute assessment locking within an unlocked milestone
1289
+ * Assessment locks until all mandatory courses in the milestone are completed
1290
+ */
1291
+ computeAssessmentLockingInMilestone(milestoneId) {
1292
+ const milestone = this.hashmap[milestoneId];
1293
+ if (!milestone)
1294
+ return;
1295
+ console.log(`Computing assessment locking for milestone: ${milestoneId}`);
1296
+ // Find assessment in this milestone
1297
+ let assessmentId = null;
1298
+ let assessment = null;
1299
+ for (const key of Object.keys(this.hashmap)) {
1300
+ const item = this.hashmap[key];
1301
+ // Check if this is an assessment that belongs to this milestone
1302
+ // Must have BOTH: correct category/mimeType AND parent is milestone
1303
+ const isAssessment = (item.primaryCategory === 'Course Assessment' ||
1304
+ item.primaryCategory === 'Final Assessment' ||
1305
+ item.primaryCategory === 'Standalone Assessment' ||
1306
+ item.mimeType === 'application/vnd.sunbird.questionset' ||
1307
+ item.mimeType === 'application/quiz') && item.parent === milestoneId; // MUST be direct child of milestone
1308
+ if (isAssessment) {
1309
+ assessmentId = key;
1310
+ assessment = item;
1311
+ console.log(`✅ Found milestone assessment: ${item.name} (${key})`);
1312
+ break;
1313
+ }
1314
+ }
1315
+ if (!assessmentId || !assessment) {
1316
+ console.log(`No assessment found in milestone ${milestoneId}`);
1317
+ return;
1318
+ }
1319
+ // Check if assessment is already completed - re-read from hashmap to get latest data
1320
+ const latestAssessment = this.hashmap[assessmentId];
1321
+ const assessmentCompleted = latestAssessment.completionStatus === 2 ||
1322
+ latestAssessment.status === 2 ||
1323
+ latestAssessment.completionPercentage >= 100;
1324
+ if (assessmentCompleted) {
1325
+ this.hashmap[assessmentId].isAssessmentLocked = false;
1326
+ this.hashmap[assessmentId].assessmentLockMessage = '';
1327
+ console.log(`Assessment ${assessmentId} is completed - unlocking`);
1328
+ return;
1329
+ }
1330
+ // Count mandatory courses and check their completion
1331
+ let mandatoryCount = 0;
1332
+ let completedMandatoryCount = 0;
1333
+ for (const key of Object.keys(this.hashmap)) {
1334
+ const item = this.hashmap[key];
1335
+ // Skip the assessment itself
1336
+ if (key === assessmentId)
1337
+ continue;
1338
+ // Check if item belongs to this milestone
1339
+ let belongsToMilestone = false;
1340
+ if (item.parent === milestoneId) {
1341
+ belongsToMilestone = true;
1342
+ }
1343
+ else if (item.parent && this.hashmap[item.parent]) {
1344
+ const parentItem = this.hashmap[item.parent];
1345
+ if (parentItem.parent === milestoneId && parentItem.primaryCategory === 'Course') {
1346
+ belongsToMilestone = true;
1347
+ }
1348
+ }
1349
+ if (!belongsToMilestone)
1350
+ continue;
1351
+ // Check if this is an assessment (skip other assessments)
1352
+ const isItemAssessment = item.primaryCategory === 'Course Assessment' ||
1353
+ item.primaryCategory === 'Final Assessment' ||
1354
+ item.primaryCategory === 'Standalone Assessment' ||
1355
+ item.mimeType === 'application/vnd.sunbird.questionset' ||
1356
+ item.mimeType === 'application/quiz' ||
1357
+ (item.name && item.name.toLowerCase().includes('assessment'));
1358
+ if (isItemAssessment)
1359
+ continue;
1360
+ // Check if this is mandatory content
1361
+ // By default, courses are mandatory unless explicitly marked otherwise
1362
+ const isMandatory = item.isMandatory !== false &&
1363
+ (item.primaryCategory === 'Course' || item.isMandatory === true);
1364
+ if (isMandatory) {
1365
+ mandatoryCount++;
1366
+ const isCompleted = item.completionStatus === 2 ||
1367
+ item.status === 2 ||
1368
+ item.completionPercentage >= 100 ||
1369
+ item.progress >= 100;
1370
+ if (isCompleted) {
1371
+ completedMandatoryCount++;
1372
+ }
1373
+ }
1374
+ }
1375
+ // Determine if assessment should be locked
1376
+ const allMandatoryComplete = mandatoryCount === 0 || completedMandatoryCount >= mandatoryCount;
1377
+ this.hashmap[assessmentId].isAssessmentLocked = !allMandatoryComplete;
1378
+ this.hashmap[assessmentId].assessmentLockMessage = !allMandatoryComplete ?
1379
+ 'This content is locked. Complete all mandatory items to unlock the assessment.' : '';
1380
+ console.log(`Assessment ${assessmentId} locking:`, {
1381
+ mandatoryCount,
1382
+ completedMandatoryCount,
1383
+ isLocked: !allMandatoryComplete
1384
+ });
1385
+ }
1386
+ /**
1387
+ * Mark all children of a milestone as parent-locked or unlocked
1388
+ */
1389
+ markMilestoneChildrenAsParentLocked(milestoneId, isLocked) {
1390
+ for (const key of Object.keys(this.hashmap)) {
1391
+ const item = this.hashmap[key];
1392
+ // Direct children of milestone
1393
+ if (item.parent === milestoneId) {
1394
+ this.hashmap[key].isParentMilestoneLocked = isLocked;
1395
+ // Also mark nested children (e.g., resources inside courses)
1396
+ if (item.children) {
1397
+ this.markNestedChildrenAsParentLocked(key, isLocked);
1398
+ }
1399
+ }
1400
+ }
1401
+ }
1402
+ /**
1403
+ * Recursively mark nested children as parent-locked
1404
+ */
1405
+ markNestedChildrenAsParentLocked(parentId, isLocked) {
1406
+ for (const key of Object.keys(this.hashmap)) {
1407
+ const item = this.hashmap[key];
1408
+ if (item.parent === parentId) {
1409
+ this.hashmap[key].isParentMilestoneLocked = isLocked;
1410
+ // Recurse for deeper nesting
1411
+ if (item.children) {
1412
+ this.markNestedChildrenAsParentLocked(key, isLocked);
1413
+ }
1414
+ }
1415
+ }
1416
+ }
1417
+ getCalculationsFromChildren(item) {
1418
+ item['duration'] = item.children.reduce((sum, child) => {
1419
+ return sum + Number(child.duration || 0);
1420
+ }, 0);
1421
+ const completedItems = _.filter(item.children, r => r.completionStatus === 2 || r.completionPercentage === 100);
1422
+ const totalCount = _.toInteger(_.get(item, 'leafNodesCount')) || 1;
1423
+ item['completionPercentage'] = Number(((completedItems.length / totalCount) * 100).toFixed());
1424
+ item['completionStatus'] = (item.completionPercentage >= 100) ? 2 : 1;
1425
+ return item;
1426
+ }
1427
+ fetchContentHistoryV2(req) {
1428
+ req.request.fields = ['progressdetails'];
1429
+ if (req.request.courseId) {
1430
+ const reslut = this.http.post(`${API_END_POINTS.CONTENT_HISTORYV2}/${req.request.courseId}`, req);
1431
+ // data.subscribe((subscribeData: any) => {
1432
+ // this.programChildCourseResumeData.next({ resumeData: subscribeData.result.contentList, courseId: req.request.courseId })
1433
+ // })
1434
+ return reslut;
1435
+ }
1436
+ return of();
1437
+ }
1438
+ dowonloadCertificate(certId) {
1439
+ return this.http.get(API_END_POINTS.CERT_DOWNLOAD(certId));
1440
+ }
1441
+ getServerDate() {
1442
+ return this.http.get(API_END_POINTS.SERVER_DATE);
1443
+ }
1444
+ getFormById(formId) {
1445
+ return this.http.get(API_END_POINTS.GET_FORM_BYID(formId));
1446
+ }
1447
+ submitForm(formData) {
1448
+ return this.http.post(API_END_POINTS.SUBMIT_FORM, formData);
1449
+ }
1450
+ getFormByIdPublic(formId) {
1451
+ return this.http.get(API_END_POINTS.GET_FORM_BYID_PUBLIC(formId));
1452
+ }
1453
+ submitFormPublic(formData) {
1454
+ return this.http.post(API_END_POINTS.SUBMIT_FORM_PUBLIC, formData);
1455
+ }
1456
+ getApllicationsById(formId, contextId) {
1457
+ return this.http.get(API_END_POINTS.GET_APPLICATIONS_BY_ID(formId, contextId));
1458
+ }
1459
+ shareContent(reqBody) {
1460
+ return this.http.post(`${API_END_POINTS.SHARE_CONTENT}`, reqBody);
1461
+ }
1462
+ checkModuleWiseData(content) {
1463
+ if (content && content.children) {
1464
+ content.children.forEach((ele) => {
1465
+ if (ele.primaryCategory === NsContent.EPrimaryCategory.MODULE) {
1466
+ let moduleResourseCount = 0;
1467
+ let offlineResourseCount = 0;
1468
+ ele.children.forEach((childEle) => {
1469
+ if (childEle.primaryCategory !== NsContent.EPrimaryCategory.OFFLINE_SESSION) {
1470
+ moduleResourseCount = moduleResourseCount + 1;
1471
+ }
1472
+ else {
1473
+ offlineResourseCount = offlineResourseCount + 1;
1474
+ }
1475
+ });
1476
+ ele['moduleResourseCount'] = moduleResourseCount;
1477
+ ele['offlineResourseCount'] = offlineResourseCount;
1478
+ }
1479
+ else {
1480
+ if (ele.primaryCategory === NsContent.EPrimaryCategory.COURSE) {
1481
+ this.checkModuleWiseData(ele);
1482
+ }
1483
+ }
1484
+ });
1485
+ }
1486
+ }
1487
+ async fetchCourseHeirarchy(contentData) {
1488
+ if (contentData && contentData.children) {
1489
+ for (const ele of contentData.children) {
1490
+ if (ele.primaryCategory === NsContent.ECourseCategory.COURSE) {
1491
+ await this.widgetSvc.fetchContent(ele.identifier).toPromise().then(async (subEle) => {
1492
+ if (subEle.result && subEle.result.content
1493
+ && subEle.result.content.children && subEle.result.content.children.length) {
1494
+ ele['children'] = subEle.result.content.children;
1495
+ }
1496
+ });
1497
+ }
1498
+ }
1499
+ }
1500
+ }
1501
+ setTranscriptionData(data) {
1502
+ // console.log('data--', data)
1503
+ this.transriptionDataSubject.next(data);
1504
+ }
1505
+ setActiveSubtitleLanguage(activeLang) {
1506
+ this.transriptionActiveLanguageDataObject.next(activeLang);
1507
+ }
1508
+ aiGetResourceVttFile(resourceID) {
1509
+ return this.http.get(`${API_END_POINTS.AI_RESOURCE_VTT_FILE}?resource_id=${resourceID}`);
1510
+ }
1511
+ readPreEnrollmentResourcesState(req) {
1512
+ return this.http
1513
+ .post(`${API_END_POINTS.PRE_ENROLLMENT_STATE_READ}`, req);
1514
+ }
1515
+ createContentV2(requestBody) {
1516
+ return this.http
1517
+ .post(`${API_END_POINTS.CREATE_RESOURCE}`, requestBody)
1518
+ .pipe(map((data) => {
1519
+ return data.result.identifier;
1520
+ }));
1521
+ }
1522
+ uploadAssignmentAnswer(contentId, batchId, assignmentId, file) {
1523
+ const formData = new FormData();
1524
+ formData.append('file', file, file.name);
1525
+ return this.http.post(`${API_END_POINTS.UPLOAD_ASSIGNMENT}/${contentId}/${batchId}/${assignmentId}`, formData);
1526
+ }
1527
+ readContentV2(id) {
1528
+ return this.http.get(`${API_END_POINTS.READ_RESOURCE}read/${id}?mode=edit`).pipe(map((data) => {
1529
+ return data.result.content;
1530
+ }));
1531
+ }
1532
+ upload(data, contentData, options) {
1533
+ const file = data.get('content');
1534
+ let fileName = file.name;
1535
+ if (['channel.json'].indexOf(fileName) < 0) {
1536
+ fileName = this.appendToFilename(fileName);
1537
+ }
1538
+ const newFormData = new FormData();
1539
+ newFormData.append('data', file, fileName);
1540
+ return this.http.post(`${API_END_POINTS.UPLOAD_FILE}upload/${contentData.contentId}`, newFormData, options);
1541
+ }
1542
+ appendToFilename(filename) {
1543
+ const timeStamp = new Date().getTime();
1544
+ const dotIndex = filename.lastIndexOf('.');
1545
+ if (dotIndex === -1) {
1546
+ return filename + timeStamp;
1547
+ }
1548
+ return filename.substring(0, dotIndex) + timeStamp + filename.substring(dotIndex);
1549
+ }
1550
+ updateContentWithFewFields(requestBody, identifier) {
1551
+ return this.http.patch(`${API_END_POINTS.UPDATE_RESOURCE}/${identifier}`, requestBody);
1552
+ }
1553
+ searchAssignments(request) {
1554
+ return this.http.post(API_END_POINTS.SEARCH, request);
1555
+ }
1556
+ submitDraftAssignment(request) {
1557
+ return this.http.put(API_END_POINTS.SUBMIT_DRAFT_ASSIGNMENT, request);
1558
+ }
1559
+ submitAssignment(request) {
1560
+ return this.http.post(API_END_POINTS.SUBMIT_ASSIGNMENT, request);
1561
+ }
1562
+ notifyAssignmentSubmission(payload) {
1563
+ return this.http.post(API_END_POINTS.NOTIFY_ASSIGNMENT_SUBMISSION, payload);
1564
+ }
1565
+ getAssignmentStatus(request) {
1566
+ return this.http.post(`${API_END_POINTS.ASSIGNMENT_STATUS}`, request);
1567
+ }
1568
+ readAssignmentFile(contentId, batchId, assignmentId, fileName) {
1569
+ // Properly encode the parameters to avoid malformed request errors
1570
+ const encodedParams = new URLSearchParams({
1571
+ contentId: contentId || '',
1572
+ batchId: batchId || '',
1573
+ formId: assignmentId || '',
1574
+ fileName: fileName || ''
1575
+ });
1576
+ return this.http.get(`${API_END_POINTS.READ_ASSIGNMENT}?${encodedParams.toString()}`, {
1577
+ responseType: 'blob',
1578
+ headers: {
1579
+ 'Accept': 'application/octet-stream, application/pdf, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document'
1580
+ }
1581
+ }).pipe(catchError((error) => {
1582
+ return throwError(() => error);
1583
+ }));
1584
+ }
1585
+ /**
1586
+ * Generate milestone achievement
1587
+ * @param userId User ID
1588
+ * @param courseId Course identifier
1589
+ * @param batchId Batch ID
1590
+ * @param milestoneId Milestone identifier (e.g., 'm1', 'm2')
1591
+ */
1592
+ generateMilestoneAchievement(userId, courseId, batchId, milestoneId) {
1593
+ const apiUrl = '/apis/proxies/v8/achievement/dynamic/v1/generate';
1594
+ const request = {
1595
+ request: {
1596
+ userId,
1597
+ courseId,
1598
+ batchId,
1599
+ milestoneId
1600
+ }
1601
+ };
1602
+ return this.http.post(apiUrl, request);
1603
+ }
1604
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AppTocService, deps: [{ token: i1.HttpClient }, { token: i2.ContentLanguageService }, { token: i3.ConfigurationsService }, { token: i4.WidgetContentService }], target: i0.ɵɵFactoryTarget.Injectable }); }
1605
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AppTocService, providedIn: 'root' }); }
1606
+ }
1607
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AppTocService, decorators: [{
1608
+ type: Injectable,
1609
+ args: [{
1610
+ providedIn: 'root'
1611
+ }]
1612
+ }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: i2.ContentLanguageService }, { type: i3.ConfigurationsService }, { type: i4.WidgetContentService }]; } });
1613
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLXRvYy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vbGlicmFyeS9zdW5iaXJkLWNiL3RvYy9zcmMvbGliL3NlcnZpY2VzL2FwcC10b2Muc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFBO0FBRTFDLE9BQU8sRUFBRSxPQUFPLEVBQWMsS0FBSyxFQUFnQixlQUFlLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBRSxNQUFNLE1BQU0sQ0FBQTtBQUVoRyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sbUNBQW1DLENBQUE7QUFDN0QsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sd0NBQXdDLENBQUE7QUFFM0UsT0FBTyxFQUFFLFFBQVEsRUFBYSxNQUFNLHlCQUF5QixDQUFBO0FBRTdELDJCQUEyQjtBQUMzQixPQUFPLENBQUMsTUFBTSxRQUFRLENBQUE7QUFFdEIsT0FBTyxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQTs7Ozs7O0FBRWhELHVDQUF1QztBQUN2QyxNQUFNLGlCQUFpQixHQUFHLG9CQUFvQixDQUFBO0FBQzlDLE1BQU0sYUFBYSxHQUFHLGtCQUFrQixDQUFBO0FBRXhDLE1BQU0sY0FBYyxHQUFHO0lBQ3JCLFlBQVksRUFBRSxHQUFHLGFBQWEsaUNBQWlDO0lBQy9ELGVBQWUsRUFBRSxHQUFHLGlCQUFpQixrQkFBa0I7SUFDdkQsWUFBWSxFQUFFLEdBQUcsaUJBQWlCLGVBQWU7SUFDakQsaUJBQWlCLEVBQUUsdUNBQXVDO0lBQzFELGNBQWMsRUFBRSxDQUFDLFNBQWlCLEVBQUUsRUFBRSxDQUFDLEdBQUcsaUJBQWlCLFlBQVksU0FBUyxTQUFTO0lBQ3pGLG1CQUFtQixFQUFFLENBQUMsU0FBaUIsRUFBRSxPQUFlLEVBQUUsR0FBVyxFQUFFLEVBQUUsQ0FDdkUsaURBQWlELFNBQVMsWUFBWSxPQUFPLFFBQVEsR0FBRyxFQUFFO0lBQzVGLE9BQU8sRUFBRSxDQUFDLFVBQWtDLEVBQUUsU0FBaUIsRUFBRSxFQUFFLENBQ2pFLEdBQUcsaUJBQWlCLFlBQVksVUFBVSxJQUFJLFNBQVMsRUFBRTtJQUMzRCxnQkFBZ0IsRUFBRSxDQUFDLFNBQWlCLEVBQUUsRUFBRSxDQUN0QyxHQUFHLGlCQUFpQiw0QkFBNEIsU0FBUyxFQUFFO0lBQzdELGtCQUFrQixFQUFFLENBQUMsT0FBZSxFQUFFLEVBQUUsQ0FBQyxHQUFHLGlCQUFpQixZQUFZLE9BQU8sRUFBRTtJQUNsRixnQkFBZ0IsRUFBRSxDQUFDLFNBQWlCLEVBQUUsV0FBbUIsRUFBRSxFQUFFLENBQzNELEdBQUcsaUJBQWlCLCtCQUErQixTQUFTLElBQUksV0FBVyxFQUFFO0lBQy9FLGVBQWUsRUFBRSxDQUFDLFNBQWlCLEVBQUUsRUFBRSxDQUNyQyxHQUFHLGlCQUFpQixrQ0FBa0MsU0FBUyxFQUFFO0lBQ25FLFdBQVcsRUFBRSxDQUFDLFNBQWlCLEVBQUUsRUFBRSxDQUNqQyxHQUFHLGFBQWEsMkJBQTJCLFNBQVMsRUFBRTtJQUN4RCxhQUFhLEVBQUUsQ0FBQyxNQUFXLEVBQUUsRUFBRSxDQUFDLEdBQUcsaUJBQWlCLHVDQUF1QyxNQUFNLEVBQUU7SUFDbkcsV0FBVyxFQUFFLDJCQUEyQjtJQUN4QyxhQUFhLEVBQUUsNENBQTRDO0lBQzNELGFBQWEsRUFBRSxDQUFDLE1BQWMsRUFBRSxFQUFFLENBQUMsK0NBQStDLE1BQU0sRUFBRTtJQUMxRiwyREFBMkQ7SUFDM0QsV0FBVyxFQUFFLHlDQUF5QztJQUN0RCxvQkFBb0IsRUFBRSxDQUFDLE1BQWMsRUFBRSxFQUFFLENBQUMscURBQXFELE1BQU0sRUFBRTtJQUN2RyxrQkFBa0IsRUFBRSwrQ0FBK0M7SUFDbkUsdUJBQXVCO0lBQ3ZCLHNCQUFzQixFQUFFLENBQUMsTUFBYyxFQUFFLFNBQWlCLEVBQUUsRUFBRSxDQUFDLHdEQUF3RCxNQUFNLGNBQWMsU0FBUyxFQUFFO0lBQ3RKLG9CQUFvQixFQUFFLEdBQUcsYUFBYSw4QkFBOEI7SUFDcEUsdUZBQXVGO0lBQ3ZGLHlCQUF5QixFQUFFLHdDQUF3QztJQUNuRSxlQUFlLEVBQUUsMENBQTBDO0lBQzNELGFBQWEsRUFBRSxvQ0FBb0M7SUFDbkQsV0FBVyxFQUFFLDJDQUEyQztJQUN4RCxlQUFlLEVBQUUsMENBQTBDO0lBQzNELE1BQU0sRUFBRSxzQ0FBc0M7SUFDOUMsdUJBQXVCLEVBQUUsMkNBQTJDO0lBQ3BFLGlCQUFpQixFQUFFLHNDQUFzQztJQUN6RCxpQkFBaUIsRUFBRSw2Q0FBNkM7SUFDaEUsaUJBQWlCLEVBQUUsaURBQWlEO0lBQ3BFLGVBQWUsRUFBRSwyREFBMkQ7SUFDNUUsNEJBQTRCLEVBQUUsNENBQTRDO0NBQzNFLENBQUE7QUFLRCxNQUFNLE9BQU8sYUFBYTtJQThCeEIsWUFBb0IsSUFBZ0IsRUFBVSxjQUFzQyxFQUFVLFNBQWdDLEVBQVUsU0FBK0I7UUFBbkosU0FBSSxHQUFKLElBQUksQ0FBWTtRQUFVLG1CQUFjLEdBQWQsY0FBYyxDQUF3QjtRQUFVLGNBQVMsR0FBVCxTQUFTLENBQXVCO1FBQVUsY0FBUyxHQUFULFNBQVMsQ0FBc0I7UUE3QnZLLDJCQUFzQixHQUFpQixJQUFJLE9BQU8sRUFBRSxDQUFBO1FBQ3BELHlCQUFvQixHQUFpQixNQUFNLENBQUE7UUFDM0MsdUJBQWtCLEdBQWlCLElBQUksT0FBTyxFQUFFLENBQUE7UUFDaEQsd0JBQW1CLEdBQWlCLElBQUksT0FBTyxFQUFFLENBQUE7UUFDakQscUJBQWdCLEdBQWlCLElBQUksT0FBTyxFQUFFLENBQUE7UUFDOUMscUJBQWdCLEdBQWlCLElBQUksT0FBTyxFQUFFLENBQUE7UUFDOUMsZUFBVSxHQUFvRCxJQUFJLE9BQU8sRUFBTyxDQUFBO1FBQ3hFLDBCQUFxQixHQUFHLEtBQUssQ0FBQTtRQUM3Qix1QkFBa0IsR0FBRyxLQUFLLENBQUE7UUFDbEMsMkJBQXNCLEdBQXdCLElBQUksQ0FBQTtRQUNsRCxvQkFBZSxHQUFHLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQTtRQUNwQyxrQkFBYSxHQUFHLElBQUksZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ2xELDRCQUF1QixHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxFQUFFLENBQUE7UUFDcEQsZUFBVSxHQUFHLElBQUksZUFBZSxDQUFDLEVBQUUsQ0FBQyxDQUFBO1FBQzNDLHNCQUFpQixHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsWUFBWSxFQUFFLENBQUE7UUFDM0Msa0JBQWEsR0FBRyxJQUFJLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUNqRCxtQkFBYyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxFQUFFLENBQUE7UUFDM0Msa0JBQWEsR0FBRyxJQUFJLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUNoRCxxQkFBZ0IsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksRUFBRSxDQUFBO1FBQzdDLFlBQU8sR0FBUSxFQUFFLENBQUE7UUFDakIsbUJBQWMsR0FBRyxJQUFJLGVBQWUsQ0FBTSxJQUFJLENBQUMsQ0FBQTtRQUN0RCxvQkFBZSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxFQUFFLENBQUE7UUFDNUMsNEJBQXVCLEdBQUcsSUFBSSxlQUFlLENBQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyxrQkFBa0I7UUFDcEYsdUJBQWtCLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLFlBQVksRUFBRSxDQUFDO1FBQzFELHlDQUFvQyxHQUFHLElBQUksZUFBZSxDQUFNLElBQUksQ0FBQyxDQUFDO1FBQ3RFLDBDQUFxQyxHQUFHLElBQUksQ0FBQyxvQ0FBb0MsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNqRywyQkFBc0IsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDLENBQUMsa0JBQWtCO1FBQ2pFLHFDQUFnQyxHQUFHLElBQUksT0FBTyxFQUFFLENBQUE7UUFDaEQsMkJBQXNCLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQTtRQUVwQywrQ0FBK0M7UUFDL0MsSUFBSSxDQUFDLHNCQUFzQixHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUNyRCxDQUFDLFdBQWdCLEVBQUUsRUFBRTtRQUNyQixDQUFDLENBQUMsQ0FBQTtJQUNOLENBQUM7SUFFRCxJQUFJLGlCQUFpQjtRQUNuQixPQUFPLElBQUksQ0FBQyxxQkFBcUIsQ0FBQTtJQUNuQyxDQUFDO0lBQ0QsSUFBSSxpQkFBaUIsQ0FBQyxHQUFZO1FBQ2hDLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxHQUFHLENBQUE7SUFDbEMsQ0FBQztJQUNELElBQUksZUFBZTtRQUNqQixPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQTtJQUNoQyxDQUFDO0lBQ0QsSUFBSSxlQUFlLENBQUMsR0FBWTtRQUM5QixJQUFJLENBQUMsa0JBQWtCLEdBQUcsR0FBRyxDQUFBO0lBQy9CLENBQUM7SUFFRCxlQUFlO1FBQ2IsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksRUFBRSxDQUFBO0lBQ2hDLENBQUM7SUFFRCxZQUFZLENBQUMsSUFBa0M7UUFDN0MsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUNyQyxDQUFDO0lBRUQsU0FBUyxDQUFDLElBQVM7UUFDakIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUNsQyxDQUFDO0lBRUQsZ0JBQWdCLENBQUMsSUFBUztRQUN4QixJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUM1QixDQUFDO0lBRUQsbUJBQW1CLENBQUMsS0FBYztRQUNoQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUNoQyxDQUFDO0lBQ0Qsb0JBQW9CLENBQUMsSUFBUztRQUM1QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO0lBQ2xDLENBQUM7SUFFRCxnQkFBZ0IsQ0FBQyxLQUFVO1FBQ3pCLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQzdCLENBQUM7SUFFRCw4QkFBOEIsQ0FBQyxTQUFjLEVBQUUsY0FBb0I7UUFDakUsSUFBSSxjQUFjLElBQUksY0FBYyxDQUFDLE1BQU0sRUFBRTtZQUMzQyxJQUFJLGNBQWMsSUFBSSxjQUFjLENBQUMsTUFBTSxJQUFJLFNBQVMsQ0FBQyxPQUFPLElBQUksU0FBUyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUU7Z0JBQzVGLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxTQUFTLEVBQUUsY0FBYyxDQUFDLENBQUE7YUFDNUQ7U0FDRjthQUFNO1lBQ0wsSUFBSSxDQUFDLHNCQUFzQixHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUNyRCxDQUFDLFVBQWUsRUFBRSxFQUFFO2dCQUNsQixJQUFJLFVBQVUsSUFBSSxVQUFVLENBQUMsTUFBTSxJQUFJLFNBQVMsQ0FBQyxPQUFPLElBQUksU0FBUyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUU7b0JBQ3BGLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxTQUFTLEVBQUUsVUFBVSxDQUFDLENBQUE7aUJBQ3hEO1lBQ0gsQ0FBQyxFQUNELEdBQUcsRUFBRTtnQkFDSCxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTtZQUNoQyxDQUFDLENBQUMsQ0FBQTtTQUNMO0lBRUgsQ0FBQztJQUNELDJCQUEyQixDQUFDLFNBQWMsRUFBRSxjQUFtQjtRQUM3RCxJQUFJLGNBQWMsSUFBSSxjQUFjLENBQUMsTUFBTSxFQUFFO1lBQzNDLElBQUksU0FBUyxJQUFJLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO2dCQUNuQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLGVBQWU7Z0JBQ3BDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDLGlCQUFpQixFQUN0RDtnQkFDQSxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFPLEVBQUUsRUFBRTtvQkFDckUsTUFBTSxZQUFZLEdBQUcsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQU8sRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLFNBQVMsS0FBSyxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUE7b0JBQ3BGLElBQUksWUFBWSxFQUFFO3dCQUNoQixFQUFFLENBQUMsb0JBQW9CLEdBQUcsWUFBWSxDQUFDLG9CQUFvQixDQUFBO3dCQUMzRCxFQUFFLENBQUMsZ0JBQWdCLEdBQUcsWUFBWSxDQUFDLE1BQU0sQ0FBQTt3QkFDekMsRUFBRSxDQUFDLGlCQUFpQixHQUFHLFlBQVksQ0FBQyxpQkFBaUIsQ0FBQTtxQkFDdEQ7Z0JBQ0gsQ0FBQyxDQUFDLENBQUE7Z0JBQ0YsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7YUFDL0I7U0FDRjtJQUNILENBQUM7SUFFRCxlQUFlLENBQUMsT0FBa0M7UUFDaEQsTUFBTSxNQUFNLEdBQUc7WUFDYixJQUFJLEVBQUUsS0FBSztZQUNYLEdBQUcsRUFBRSxFQUFFO1NBQ1IsQ0FBQTtRQUNELElBQUksT0FBTyxFQUFFO1lBQ1gsSUFDRSxPQUFPLENBQUMsV0FBVyxJQUFJLE9BQU8sQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQztnQkFDakUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXO2dCQUMxQixJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxPQUFPLEtBQUssT0FBTyxFQUM5QztnQkFDQSxNQUFNLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQTtnQkFDbkIsTUFBTSxDQUFDLEdBQUcsR0FBRyxrQkFBa0IsQ0FBQTtnQkFDL0IsT0FBTyxNQUFNLENBQUE7YUFDZDtZQUNELElBQUksT0FBTyxDQUFDLFlBQVksS0FBSyxlQUFlLEVBQUU7Z0JBQzVDLE1BQU0sQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFBO2dCQUNsQixPQUFPLE1BQU0sQ0FBQTthQUNkO1NBQ0Y7UUFDRCxPQUFPLE1BQU0sQ0FBQTtJQUNmLENBQUM7SUFFRCxRQUFRLENBQUMsSUFBVSxFQUFFLGlCQUEwQixLQUFLO1FBQ2xELElBQUksT0FBTyxHQUE4QixJQUFJLENBQUE7UUFDN0MsSUFBSSxTQUFTLEdBQW9DLElBQUksQ0FBQTtRQUNyRCxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUM3QixJQUFJLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQ3JFLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQTtZQUMzQixJQUFJLGNBQWMsRUFBRTtnQkFDbEIsSUFBSSxDQUFDLHNCQUFzQixHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUNyRCxDQUFDLFVBQWUsRUFBRSxFQUFFO29CQUNsQixJQUFJLFVBQVUsSUFBSSxVQUFVLENBQUMsTUFBTSxFQUFFO3dCQUNuQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTt3QkFDN0IsSUFBSSxDQUFDLHVCQUF1QixDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsQ0FBQTtxQkFDbEQ7Z0JBQ0gsQ0FBQyxFQUNELEdBQUcsRUFBRTtvQkFDSCx1Q0FBdUM7b0JBQ3ZDLE9BQU8sQ0FBQyxHQUFHLENBQUMsaUNBQWlDLENBQUMsQ0FBQTtnQkFDaEQsQ0FBQyxDQUNGLENBQUE7YUFDRjtpQkFBTTtnQkFDTCxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTthQUMvQjtTQUNGO2FBQU07WUFDTCxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTtZQUM5QixJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUU7Z0JBQ2QsU0FBUyxHQUFHLFFBQVEsQ0FBQyxlQUFlLENBQUMsV0FBVyxDQUFBO2FBQ2pEO2lCQUFNO2dCQUNMLFNBQVMsR0FBRyxRQUFRLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQTthQUM3QztTQUNGO1FBQ0QsaUNBQWlDO1FBQ2pDLE9BQU87WUFDTCxPQUFPO1lBQ1AsU0FBUztTQUNWLENBQUE7SUFDSCxDQUFDO0lBRUQsdUJBQXVCLENBQUMsT0FBa0MsRUFBRSxVQUFlO1FBQ3pFLElBQUksT0FBTyxJQUFJLE9BQU8sQ0FBQyxRQUFRLEVBQUU7WUFDL0IsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUU7Z0JBQzNCLE1BQU0sWUFBWSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFPLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxTQUFTLEtBQUssS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFBO2dCQUNwRixJQUFJLFlBQVksRUFBRTtvQkFDaEIsS0FBSyxDQUFDLG9CQUFvQixHQUFHLFlBQVksQ0FBQyxvQkFBb0IsSUFBSSxZQUFZLENBQUMsUUFBUSxDQUFBO29CQUN2RixLQUFLLENBQUMsZ0JBQWdCLEdBQUcsWUFBWSxDQUFDLE1BQU0sQ0FBQTtpQkFDN0M7cUJBQU07b0JBQ0wsSUFBSSxDQUFDLHVCQUF1QixDQUFDLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQTtpQkFDaEQ7WUFDSCxDQUFDLENBQUMsQ0FBQTtZQUNGLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO1NBQy9CO2FBQU07WUFDTCxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTtTQUMvQjtJQUNILENBQUM7SUFFRCxjQUFjLENBQUMsT0FBMkI7UUFDeEMsSUFBSSxPQUFPLElBQUksT0FBTyxDQUFDLFFBQVEsRUFBRTtZQUMvQixPQUFPLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRTtnQkFDM0IsSUFBSSxLQUFLLENBQUMsZUFBZSxLQUFLLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUU7b0JBQy9ELE9BQU8sQ0FBQyxhQUFhLENBQUMsR0FBRyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtpQkFDakY7Z0JBQ0QsSUFBSSxLQUFLLENBQUMsZUFBZSxLQUFLLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUU7b0JBQy9ELElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUE7aUJBQzNCO1lBQ0gsQ0FBQyxDQUFDLENBQUE7U0FDSDtJQUNILENBQUM7SUFFRCxXQUFXLENBQUMsT0FBMkIsRUFBRSxVQUFrQjtRQUN6RCxJQUFJLE9BQU8sQ0FBQyxVQUFVLEtBQUssVUFBVSxFQUFFO1lBQ3JDLE9BQU8sT0FBTyxDQUFDLFFBQVEsQ0FBQTtTQUN4QjtRQUNELElBQUksT0FBTyxJQUFJLE9BQU8sQ0FBQyxRQUFRLEVBQUU7WUFDL0IsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7Z0JBQ2pDLHVEQUF1RDtnQkFDdkQsNEJBQTRCO2dCQUM1QixJQUFJO2dCQUNKLHNCQUFzQjtnQkFDdEIsb0VBQW9FO2dCQUNwRSxPQUFPLE9BQU8sQ0FBQyxRQUFRLENBQUE7YUFDeEI7WUFDRCxNQUFNLFFBQVEsR0FBVSxFQUFFLENBQUE7WUFDMUIsTUFBTSxzQkFBc0IsR0FBUSxDQUFDLElBQXdCLEVBQUUsRUFBRTtnQkFDL0QsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtnQkFDbkIsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO29CQUNqQixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBcUIsRUFBRSxFQUFFLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtpQkFDL0U7Z0JBQ0QsT0FBTTtZQUNSLENBQUMsQ0FBQTtZQUNELHNCQUFzQixDQUFDLE9BQU8sQ0FBQyxDQUFBO1lBQy9CLE1BQU0sSUFBSSxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsRUFBRSxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUE7WUFDeEQsT0FBTyxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFBO1NBQ3JDO1FBQ0QsdUJBQXVCO1FBQ3ZCLE9BQU8sU0FBUyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUE7SUFDckMsQ0FBQztJQUVELGVBQWUsQ0FDYixPQUEyQixFQUMzQixZQUFvQztRQUVwQyxJQUNFLE9BQU87WUFDUCxDQUFDLENBQUMsT0FBTyxDQUFDLGVBQWUsS0FBSyxJQUFJLENBQUMsZUFBZSxDQUFDLFFBQVE7Z0JBQ3pELDBFQUEwRTttQkFDdkUsT0FBTyxDQUFDLGVBQWUsS0FBSyxJQUFJLENBQUMsZUFBZSxDQUFDLGlCQUFpQjttQkFDbEUsT0FBTyxDQUFDLGVBQWUsS0FBSyxJQUFJLENBQUMsZUFBZSxDQUFDLGdCQUFnQjttQkFDakUsT0FBTyxDQUFDLGVBQWUsS0FBSyxJQUFJLENBQUMsZUFBZSxDQUFDLGVBQWUsQ0FDcEUsRUFBRTtZQUNILElBQUksT0FBTyxDQUFDLGVBQWUsS0FBSyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxFQUFFO2dCQUNqRSxZQUFZLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQTthQUN6QjtpQkFBTSxJQUFJLE9BQU8sQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLE1BQU0sRUFBRTtnQkFDeEUsWUFBWSxDQUFDLGNBQWMsSUFBSSxDQUFDLENBQUE7YUFDakM7WUFDRCxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUU7Z0JBQy9CLHNEQUFzRDtnQkFDdEQsWUFBWSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxFQUFFLFlBQVksQ0FBQyxDQUFBO1lBQzFELENBQUMsQ0FBQyxDQUFBO1NBQ0g7YUFBTSxJQUNMLE9BQU87WUFDUCxDQUNFLE9BQU8sQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLFFBQVE7Z0JBQy9ELGtEQUFrRDttQkFDL0MsT0FBTyxDQUFDLGVBQWUsS0FBSyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsaUJBQWlCO21CQUN4RSxPQUFPLENBQUMsZUFBZSxLQUFLLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxnQkFBZ0I7bUJBQ3ZFLE9BQU8sQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLGVBQWUsQ0FBQyxFQUM1RTtZQUNBLFFBQVEsT0FBTyxDQUFDLFFBQVEsRUFBRTtnQkFDeEIsc0NBQXNDO2dCQUN0Qyw4QkFBOEI7Z0JBQzlCLFVBQVU7Z0JBQ1YsS0FBSyxTQUFTLENBQUMsVUFBVSxDQUFDLEdBQUc7b0JBQzNCLFlBQVksQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFBO29CQUN6QixNQUFLO2dCQUNQLEtBQUssU0FBUyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUM7Z0JBQzlCLEtBQUssU0FBUyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUM7Z0JBQy9CLEtBQUssU0FBUyxDQUFDLFVBQVUsQ0FBQyxPQUFPO29CQUMvQixZQUFZLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQTtvQkFDdkIsTUFBSztnQkFDUCx5Q0FBeUM7Z0JBQ3pDLHVDQUF1QztnQkFDdkMsVUFBVTtnQkFDVixLQUFLLFNBQVMsQ0FBQyxVQUFVLENBQUMsR0FBRztvQkFDM0IsWUFBWSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUE7b0JBQ3JCLE1BQUs7Z0JBQ1Asa0NBQWtDO2dCQUNsQyxLQUFLLFNBQVMsQ0FBQyxVQUFVLENBQUMsUUFBUTtvQkFDaEMsWUFBWSxDQUFDLE9BQU8sSUFBSSxDQUFDLENBQUE7b0JBQ3pCLE1BQUs7Z0JBQ1AsS0FBSyxTQUFTLENBQUMsVUFBVSxDQUFDLE1BQU07b0JBQzlCLFlBQVksQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFBO29CQUN4QixNQUFLO2dCQUNQLEtBQUssU0FBUyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUM7Z0JBQy9CLEtBQUssU0FBUyxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0I7b0JBQ3hDLCtDQUErQztvQkFDL0MsWUFBWSxDQUFDLFVBQVUsSUFBSSxDQUFDLENBQUE7b0JBQzVCLFdBQVc7b0JBQ1gsMkJBQTJCO29CQUMzQixJQUFJO29CQUNKLE1BQUs7Z0JBQ1AsS0FBSyxTQUFTLENBQUMsVUFBVSxDQUFDLGVBQWU7b0JBQ3ZDLCtDQUErQztvQkFDL0MsWUFBWSxDQUFDLGNBQWMsSUFBSSxDQUFDLENBQUE7b0JBQ2hDLFdBQVc7b0JBQ1gsMkJBQTJCO29CQUMzQixJQUFJO29CQUNKLE1BQUs7Z0JBQ1AsS0FBSyxTQUFTLENBQUMsVUFBVSxDQUFDLGlCQUFpQjtvQkFDekMsSUFBSSxPQUFPLENBQUMsZUFBZSxLQUFLLElBQUksQ0FBQyxlQUFlLENBQUMsaUJBQWlCLEVBQUU7d0JBQ3RFLFlBQVksQ0FBQyxZQUFZLElBQUksQ0FBQyxDQUFBO3FCQUMvQjt5QkFBTSxJQUFJLE9BQU8sQ0FBQyxlQUFlLEtBQUssSUFBSSxDQUFDLGVBQWUsQ0FBQyxnQkFBZ0IsRUFBRTt3QkFDNUUsWUFBWSxDQUFDLFNBQVMsSUFBSSxDQUFDLENBQUE7cUJBQzVCO29CQUNELE1BQUs7Z0JBQ1Asd0NBQXdDO2dCQUN4QyxnQ0FBZ0M7Z0JBQ2hDLFVBQVU7Z0JBQ1YsS0FBSyxTQUFTLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQztnQkFDL0IsS0FBSyxTQUFTLENBQUMsVUFBVSxDQUFDLEdBQUc7b0JBQzNCLFlBQVksQ0FBQyxrQkFBa0IsSUFBSSxDQUFDLENBQUE7b0JBQ3BDLE1BQUs7Z0JBQ1AscUNBQXFDO2dCQUNyQyw4QkFBOEI7Z0JBQzlCLFVBQVU7Z0JBQ1Y7b0JBQ0UsWUFBWSxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUE7b0JBQ3ZCLE1BQUs7YUFDUjtZQUNELE9BQU8sWUFBWSxDQUFBO1NBQ3BCO1FBQ0QsT0FBTyxZQUFZLENBQUE7SUFDckIsQ0FBQztJQUVELFNBQVMsQ0FDUCxPQUEyQixFQUMzQixpQkFBNEMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxHQUFHO1FBRXpFLElBQUksT0FBTyxDQUFDLGVBQWUsS0FBSyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsUUFBUTtZQUNqRSxtREFBbUQ7ZUFDaEQsT0FBTyxDQUFDLGVBQWUsS0FBSyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsaUJBQWlCO2VBQ3hFLE9BQU8sQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLGdCQUFnQjtlQUN2RSxPQUFPLENBQUMsZUFBZSxLQUFLLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxlQUFlLEVBQUU7WUFDM0UsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsT0FBTyxFQUFFLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQTtTQUN4RTtRQUNELE1BQU0sZ0JBQWdCLEdBQ3BCLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsVUFBVSxDQUFDLEVBQUUsWUFBWSxDQUFDLEVBQUUsQ0FDL0MsSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLEVBQUUsY0FBYyxDQUFDLENBQUM7YUFDNUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUF5QixDQUFBO1FBQ3hFLElBQUksZ0JBQWdCLElBQUksZ0JBQWdCLENBQUMsTUFBTSxFQUFFO1lBQy9DLE9BQU87Z0JBQ0wsR0FBRyxPQUFPO2dCQUNWLFFBQVEsRUFBRSxnQkFBZ0I7YUFDM0IsQ0FBQTtTQUNGO1FBQ0QsT0FBTyxJQUFJLENBQUE7SUFDYixDQUFDO0lBRUQsaUJBQWlCLENBQ2YsT0FBMkIsRUFDM0IsaUJBQTRDLFNBQVMsQ0FBQyxlQUFlLENBQUMsR0FBRztRQUV6RSxRQUFRLGNBQWMsRUFBRTtZQUN0QixLQUFLLFNBQVMsQ0FBQyxlQUFlLENBQUMsS0FBSztnQkFDbEMsT0FBTyxDQUNMLENBQUMsa0JBQWtCLENBQUMsd0JBQXdCLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUM7b0JBQ3RFLENBQUMsa0JBQWtCLENBQUMsMEJBQTBCLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FDekUsQ0FBQTtZQUNILEtBQUssU0FBUyxDQUFDLGVBQWUsQ0FBQyxRQUFRO2dCQUNyQyxPQUFPLGtCQUFrQixDQUFDLHdCQUF3QixDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUE7WUFDOUUsS0FBSyxTQUFTLENBQUMsZUFBZSxDQUFDLE1BQU07Z0JBQ25DLE9BQU8sa0JBQWtCLENBQUMsMEJBQTBCLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQTtZQUNoRixLQUFLLFNBQVMsQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDO1lBQ25DO2dCQUNFLE9BQU8sSUFBSSxDQUFBO1NBQ2Q7SUFDSCxDQUFDO0lBQ0QsK0JBQStCLENBQUMsU0FBaUI7UUFDL0MsSUFBSSxJQUFJLENBQUMsb0JBQW9CLEtBQUssVUFBVSxJQUFJLElBQUksQ0FBQyxvQkFBb0IsS0FBSyxNQUFNLEVBQUU7WUFDcEYsSUFBSSxDQUFDLHlCQUF5QixDQUFDLFNBQVMsQ0FBQyxDQUFBO1NBQzFDO0lBQ0gsQ0FBQztJQUNPLHlCQUF5QixDQUFDLFNBQWlCO1FBQ2pELElBQUksQ0FBQyxvQkFBb0IsR0FBRyxVQUFVLENBQUE7UUFDdEMsTUFBTSxHQUFHLEdBQUcsR0FBRyxhQUFhLDBDQUEwQyxTQUFTLGNBQWMsQ0FBQTtRQUM3RixJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxTQUFTLENBQzFCLENBQUMsTUFBVyxFQUFFLEVBQUU7WUFDZCxJQUFJLENBQUMsb0JBQW9CLEdBQUcsTUFBTSxDQUFBO1lBQ2xDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDMUMsQ0FBQyxFQUNELEdBQUcsRUFBRTtZQUNILElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7WUFDdEMsSUFBSSxDQUFDLG9CQUFvQixHQUFHLE1BQU0sQ0FBQTtRQUNwQyxDQUFDLENBQ0YsQ0FBQTtJQUNILENBQUM7SUFFRCx5QkFBeUIsQ0FBQyxTQUFpQjtRQUN6QyxJQUFJLElBQUksQ0FBQyxvQkFBb0IsS0FBSyxVQUFVLElBQUksSUFBSSxDQUFDLG9CQUFvQixLQUFLLE1BQU0sRUFBRTtZQUNwRixJQUFJLENBQUMsbUJBQW1CLENBQUMsU0FBUyxDQUFDLENBQUE7U0FDcEM7SUFDSCxDQUFDO0lBQ08sbUJBQW1CLENBQUMsU0FBaUI7UUFDM0MsSUFBSSxDQUFDLG9CQUFvQixHQUFHLFVBQVUsQ0FBQTtRQUN0Qyw0Q0FBNEM7UUFDNUMsTUFBTSxHQUFHLEdBQUcsR0FBRyxhQUFhLHFDQUFxQyxrQkFBa0IsQ0FDakYsa0NBQWtDLENBQ25DLElBQUksa0JBQWtCLENBQUMsbUJBQW1CLFNBQVMsSUFBSSxDQUFDLEVBQUUsQ0FBQTtRQUMzRCxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxTQUFTLENBQzFCLENBQUMsTUFBVyxFQUFFLEVBQUU7WUFDZCxJQUFJLENBQUMsb0JBQW9CLEdBQUcsTUFBTSxDQUFBO1lBQ2xDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDMUMsQ0FBQyxFQUNELEdBQUcsRUFBRTtZQUNILElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7WUFDdEMsSUFBSSxDQUFDLG9CQUFvQixHQUFHLE1BQU0sQ0FBQTtRQUNwQyxDQUFDLENBQ0YsQ0FBQTtJQUNILENBQUM7SUFFRCxrQkFBa0I7UUFDaEIsSUFBSSxJQUFJLENBQUMsc0JBQXNCLEVBQUU7WUFDL0IsSUFBSSxDQUFDLHNCQUFzQixDQUFDLFdBQVcsRUFBRSxDQUFBO1NBQzFDO0lBQ0gsQ0FBQztJQUVEOzs7T0FHRztJQUNILGdCQUFnQjtRQUNkLElBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFBO1FBQ2pCLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQzlCLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0NBQXNDLENBQUMsQ0FBQTtJQUNyRCxDQUFDO0lBRUQsbUJBQW1CLENBQUMsU0FBaUI7UUFDbkMscURBQXFEO1FBQ3JELHNEQUFzRDtRQUN0RCxJQUFJO1FBQ0osSUFBSSxTQUFTLEVBQUUsR0FBRztRQUNsQixPQUFPLEtBQUssQ0FBQTtJQUNkLENBQUM7SUFDRCxxQkFBcUIsQ0FDbkIsU0FBaUIsRUFDakIsV0FBb0I7UUFFcEIsSUFBSSxXQUFXLEVBQUU7WUFDZixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUNsQixHQUFHLGNBQWMsQ0FBQyxZQUFZLElBQUksU0FBUyxnQkFBZ0IsV0FBVyxFQUFFLENBQ3pFLENBQUE7U0FDRjtRQUNELE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQ2xCLEdBQUcsY0FBYyxDQUFDLFlBQVksSUFBSSxTQUFTLE9BQU8sSUFBSSxJQUFJLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUN6RSxDQUFBO0lBQ0gsQ0FBQztJQUVELHFCQUFxQixDQUFDLFNBQWlCO1FBQ3JDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQ2xCLEdBQUcsY0FBYyxDQUFDLFlBQ2xCLElBQUksU0FBUyw2QkFBNkIsSUFBSSxJQUFJLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUNqRSxDQUFBO0lBQ0gsQ0FBQztJQUVELHFCQUFxQixDQUFDLFNBQWlCO1FBQ3JDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQ2xCLEdBQUcsY0FBYyxDQUFDLFlBQ2xCLElBQUksU0FBUyw4QkFBOEIsSUFBSSxJQUFJLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUNsRSxDQUFBO0lBQ0gsQ0FBQztJQUVELG1CQUFtQixDQUNqQixVQUFrQyxFQUNsQyxTQUFpQjtRQUVqQixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUE4QixjQUFjLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxTQUFTLENBQUMsRUFBRTtZQUMvRixPQUFPLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLElBQUksRUFBRSxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtTQUN6RyxDQUFDLENBQUE7SUFDSixDQUFDO0lBQ0QsMEJBQTBCLENBQUMsU0FBaUI7UUFDMUMsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBeUIsY0FBYyxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUE7SUFDMUYsQ0FBQztJQUNELHFCQUFxQixDQUFDLE9BQWU7UUFDbkMsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBaUMsY0FBYyxDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUE7SUFDbEcsQ0FBQztJQUNELGlCQUFpQixDQUFDLFNBQWlCLEVBQUUsV0FBbUI7UUFDdEQsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FDbEIsY0FBYyxDQUFDLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxXQUFXLENBQUMsQ0FDeEQsQ0FBQTtJQUNILENBQUM7SUFFRCx5QkFBeUIsQ0FBQyxTQUFpQjtRQUN6QyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUNsQixjQUFjLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQyxDQUMxQyxDQUFBO0lBQ0gsQ0FBQztJQUVELG1CQUFtQixDQUFDLFNBQWlCO1FBQ25DLElBQUksR0FBRyxHQUFHLEVBQUUsQ0FBQTtRQUNaLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLENBQUE7UUFDOUcsSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNmLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQ2xCLGNBQWMsQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQ3RDLENBQUE7U0FDRjtRQUNELElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUMxRixHQUFHLEdBQUcsMkNBQTJDLFNBQVMsRUFBRSxDQUFBO1NBQzdEO2FBQU07WUFDTCxHQUFHLEdBQUcsd0JBQXdCLFNBQVMsRUFBRSxDQUFBO1NBQzFDO1FBQ0QsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBa0IsR0FBRyxDQUFDLENBQUE7SUFFNUMsQ0FBQztJQUVELGtCQUFrQixDQUFDLFNBQWlCLEVBQUUsSUFBZ0MsRUFBRSxVQUFVLEdBQUcsS0FBSztRQUN4RixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUNuQixVQUFVO1lBQ1IsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxtQkFBbUIsQ0FDbEMsU0FBUyxFQUNULElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxJQUFJLEVBQUUsRUFDNUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQ2hEO1lBQ0QsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDLEVBQzVDLElBQUksQ0FDTCxDQUFBO0lBQ0gsQ0FBQztJQUVELFdBQVcsQ0FBQyxTQUFjO1FBQ3hCLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQ25CLGNBQWMsQ0FBQyxZQUFZLEVBQzNCLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxDQUN2QixDQUFBO0lBQ0gsQ0FBQztJQUVELEtBQUssQ0FBQyw4QkFBOEIsQ0FBQyxPQUFrQyxFQUFFLGFBQWtCLEVBQUUsWUFBcUI7UUFDaEgsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDN0IsSUFBSSxVQUFVLEdBQUcsQ0FBQyxDQUFBO1FBQ2xCLElBQUksYUFBYSxHQUFHLENBQUMsQ0FBQTtRQUNyQixJQUFJLGtCQUFrQixHQUFRLEVBQUUsQ0FBQTtRQUNoQyxJQUFJLHFCQUFxQixHQUFRLEVBQUUsQ0FBQTtRQUNuQyxJQUFJLG1CQUFtQixHQUFRLEVBQUUsQ0FBQTtRQUNqQyxJQUFJLE9BQU8sSUFBSSxPQUFPLENBQUMsUUFBUSxFQUFFO1lBQy9CLGFBQWEsR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFBO1lBQ3RDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1lBQzdCLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLDJCQUEyQixDQUFDLGFBQWEsRUFBRSxZQUFZLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFBO1lBQzlHLElBQUksa0JBQWtCLElBQUksa0JBQWtCLENBQUMsb0JBQW9CLEtBQUssR0FBRyxFQUFFO2dCQUN6RSxNQUFNLElBQUksQ0FBQyxtQ0FBbUMsQ0FBQyxPQUFPLENBQUMsQ0FBQTtnQkFDdkQsVUFBVSxHQUFHLE9BQU8sQ0FBQyxjQUFjLENBQUE7YUFDcEM7aUJBQU07Z0JBQ0wsSUFBSSxPQUFPLEVBQUUsZUFBZSxLQUFLLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUU7b0JBQ2xFLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFO3dCQUNuRCwwREFBMEQ7d0JBQzFELE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUE7d0JBQ3ZDLElBQUksV0FBVyxDQUFDLGVBQWUsS0FBSyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxFQUFFOzRCQUNyRSxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsMkJBQTJCLENBQUMsYUFBYSxFQUFFLFdBQVcsRUFBRSxVQUFVLENBQUMsQ0FBQTs0QkFDN0YsNENBQTRDOzRCQUM1QyxtSUFBbUk7NEJBQ25JLHdFQUF3RTs0QkFDeEUsSUFBSSxZQUFZLElBQUksWUFBWSxDQUFDLG9CQUFvQixLQUFLLEdBQUcsRUFBRTtnQ0FDN0QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7Z0NBQzdCLFVBQVUsR0FBRyxVQUFVLElBQUksV0FBVyxDQUFDLGNBQWMsQ0FBQTtnQ0FDckQsa0JBQWtCLEdBQUcsQ0FBQyxHQUFHLGtCQUFrQixFQUFFLEdBQUcsV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFBO2dDQUN0RSxJQUFJLFlBQVksQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO29DQUM5QyxNQUFNLFdBQVcsR0FBUSxZQUFZLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBTSxFQUFFLENBQU0sRUFBRSxFQUFFLENBQy9FLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxPQUFPLEVBQUUsR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQTtvQ0FDMUUsTUFBTSxNQUFNLEdBQVEsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQTtvQ0FDN0MsV0FBVyxDQUFDLG9CQUFvQixHQUFHLE1BQU0sQ0FBQTtvQ0FDekMsOEZBQThGO29DQUM5RixtQ0FBbUM7b0NBQ25DLEtBQUs7b0NBQ0wscUNBQXFDO29DQUNyQyxpRUFBaUU7b0NBQ2pFLElBQUk7b0NBQ0osSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7aUNBQy9CO2dDQUNELFdBQVcsQ0FBQyxvQkFBb0IsR0FBRyxHQUFHLENBQUE7Z0NBQ3RDLFdBQVcsQ0FBQyxnQkFBZ0IsR0FBRyxDQUFDLENBQUE7Z0NBQ2hDLE1BQU0sSUFBSSxDQUFDLG1DQUFtQyxDQUFDLFdBQVcsQ0FBQyxDQUFBOzZCQUM1RDtpQ0FBTTtnQ0FDTCxJQUFJLFlBQVksRUFBRTtvQ0FDaEIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7b0NBQzdCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDLENBQUE7b0NBQ3BFLE1BQU0sR0FBRyxHQUFHO3dDQUNWLE9BQU8sRUFBRTs0Q0FDUCxPQUFPLEVBQUUsWUFBWSxDQUFDLEtBQUssQ0FBQyxPQUFPOzRDQUNuQyxNQUFNLEVBQUUsWUFBWSxDQUFDLE1BQU07NENBQzNCLFFBQVEsRUFBRSxRQUFROzRDQUNsQixRQUFRLEVBQUUsWUFBWSxDQUFDLFlBQVk7NENBQ25DLFVBQVUsRUFBRSxFQUFFOzRDQUNkLE1BQU0sRUFBRTtnREFDTixpQkFBaUI7NkNBQ2xCO3lDQUNGO3FDQUNGLENBQUE7b0NBQ0QscUJBQXFCLEdBQUcsQ0FBQyxXQUFXLENBQUMsb0JBQW9CLEtBQUssQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLG9CQUFvQixDQUFDO3dDQUNuRyxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLHFCQUFxQixDQUFBO29DQUM5RCxtQkFBbUIsR0FBRyxtQkFBbUIsQ0FBQTtvQ0FDekMsTUFBTSxJQUFJLENBQUMscUJBQXFCLENBQUMsR0FBRyxDQUFDLENBQUMsU0FBUyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsWUFBaUIsRUFBRSxFQUFFO3dDQUMzRSxNQUFNLElBQUksR0FBUSxZQUFZLENBQUE7d0NBQzlCLElBQUksSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxNQUFNLEdBQUcsQ0FBQyxFQUFFOzRDQUN4RCxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFRLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEtBQUssR0FBRyxDQUFDLENBQUE7NENBQ3pGLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxrQkFBa0IsRUFBRSxjQUFjLENBQUMsQ0FBQTs0Q0FDaEUsVUFBVSxHQUFHLGtCQUFrQixDQUFDLE1BQU0sQ0FBQTs0Q0FDdEMsbUJBQW1CLEdBQUcsQ0FBQyxHQUFHLG1CQUFtQixFQUFFLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQTs0Q0FDMUUsNkZBQTZGOzRDQUM3RixJQUFJLENBQUMsZ0JBQWdCLENBQUMsbUJBQW1CLENBQUMsQ0FBQTs0Q0FDMUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFBOzRDQUNsRSxJQUFJLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQyxDQUFBO3lDQUNqQzs2Q0FBTTs0Q0FDTCxJQUFJLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQyxDQUFBO3lDQUNqQzt3Q0FDRCxPQUFPLFlBQVksQ0FBQTtvQ0FDckIsQ0FBQyxDQUFDLENBQUE7b0NBQ0YsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7aUNBQy9COzZCQUNGO3lCQUNGO3dCQUNELFVBQVU7d0JBQ1Ysa0ZBQWtGO3dCQUNsRixvQ0FBb0M7d0JBQ3BDLG9IQUFvSDt3QkFDcEgsMEJBQTBCO3dCQUMxQixzQkFBc0I7d0JBQ3RCLHFCQUFxQjt3QkFDckIsaURBQWlEO3dCQUNqRCx5Q0FBeUM7d0JBQ3pDLGlEQUFpRDt3QkFDakQsNEJBQTRCO3dCQUM1QixzQkFBc0I7d0JBQ3RCLGlDQUFpQzt3QkFDakMsZUFBZTt3QkFDZixhQUFhO3dCQUNiLFVBQVU7d0JBQ1Ysd0ZBQXdGO3dCQUN4RiwwQ0FBMEM7d0JBQzFDLG1FQUFtRTt3QkFDbkUsc0dBQXNHO3dCQUN0Ryw2RUFBNkU7d0JBQzdFLG1EQUFtRDt3QkFDbkQsdUdBQXVHO3dCQUN2Ryx1REFBdUQ7d0JBQ3ZELDJFQUEyRTt3QkFDM0UsWUFBWTt3QkFDWix5Q0FBeUM7d0JBQ3pDLDhCQUE4Qjt3QkFDOUIsV0FBVzt3QkFDWCxRQUFRO3dCQUNSLHFDQUFxQzt3QkFDckMsTUFBTTt3QkFDTixJQUFJO3dCQUNKLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO3FCQUMvQjtpQkFDRjtnQkFDRCxJQUFJLE9BQU8sQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLGVBQWU7dUJBQ3JFLE9BQU8sQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLE1BQU07dUJBQzdELE9BQU8sQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLHFCQUFxQjt1QkFDNUUsT0FBTyxDQUFDLGVBQWUsS0FBSyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsZUFBZSxFQUFFO29CQUMzRSx5REFBeUQ7b0JBQ3pELE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLDJCQUEyQixDQUFDLGFBQWEsRUFBRSxZQUFZLElBQUksT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFBO29CQUMvRyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxDQUFBO29CQUNoRSxNQUFNLEdBQUcsR0FBRzt3QkFDVixPQUFPLEVBQUU7NEJBQ1AsT0FBTyxFQUFFLGtCQUFrQixFQUFFLEtBQUssRUFBRSxPQUFPOzRCQUMzQyxNQUFNLEVBQUUsa0JBQWtCLEVBQUUsTUFBTTs0QkFDbEMsUUFBUSxFQUFFLGtCQUFrQixFQUFFLFlBQVk7NEJBQzFDLFFBQVEsRUFBRSxRQUFROzRCQUNsQixVQUFVLEVBQUUsRUFBRTs0QkFDZCxNQUFNLEVBQUU7Z0NBQ04saUJBQWlCOzZCQUNsQjt5QkFDRjtxQkFDRixDQUFBO29CQUNELE1BQU0sSUFBSSxDQUFDLHFCQUFxQixDQUFDLEdBQUcsQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLFlBQWlCLEVBQUUsRUFBRTt3QkFDM0UsTUFBTSxJQUFJLEdBQVEsWUFBWSxDQUFBO3dCQUM5QixJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7NEJBQzdELE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQVEsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLFFBQVEsS0FBSyxHQUFHLENBQUMsQ0FBQTs0QkFDekYsSUFBSSxDQUFDLHVCQUF1QixDQUFDLGtCQUFrQixFQUFFLGNBQWMsQ0FBQyxDQUFBOzRCQUNoRSxVQUFVLEdBQUcsa0JBQWtCLENBQUMsTUFBTSxDQUFBOzRCQUN0QyxtQkFBbUIsR0FBRyxDQUFDLEdBQUcsbUJBQW1CLEVBQUUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFBOzRCQUMxRSw2RkFBNkY7NEJBQzdGLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFBOzRCQUMxQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUE7eUJBQy9EO3dCQUNELElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO3dCQUM5QixPQUFPLFlBQVksQ0FBQTtvQkFDckIsQ0FBQyxDQUFDLENBQUE7aUJBQ0g7Z0JBRUQsSUFBSSxtQkFBbUIsSUFBSSxtQkFBbUIsQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLHFCQUFxQixFQUFFO29CQUNwRixNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLHdCQUF3QixDQUFDLHFCQUFxQixDQUFDLENBQUE7b0JBQ3JGLE1BQU0sbUJBQW1CLEdBQUcsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQU8sRUFBRSxFQUFFLENBQ3pELEVBQUUsQ0FBQyxZQUFZLEtBQUsscUJBQXFCLENBQUMsVUFBVSxDQUFDLENBQUE7b0JBQ3ZELE1BQU0sVUFBVSxHQUFHLENBQUM7NEJBQ2xCLFNBQVMsRUFBRSxjQUFjLENBQUMsVUFBVTs0QkFDcEMsT0FBTyxFQUFFLG1CQUFtQixJQUFJLG1CQUFtQixDQUFDLE9BQU87NEJBQzNELGNBQWMsRUFBRSxDQUFDOzRCQUNqQixvQkFBb0IsRUFBRSxHQUFHOzRCQUN6QixRQUFRLEVBQUUsQ0FBQzs0QkFDWCxTQUFTLEVBQUUsQ0FBQzs0QkFDWixRQUFRLEVBQUUsbUJBQW1CLElBQUksbUJBQW1CLENBQUMsUUFBUTs0QkFDN0QsWUFBWSxFQUFFLG1CQUFtQixJQUFJLG1CQUFtQixDQUFDLFFBQVE7NEJBQ2pFLE1BQU0sRUFBRSxDQUFDO3lCQUNWLENBQUMsQ0FBQTtvQkFDRixtQkFBbUIsR0FBRyxVQUFVLENBQUE7b0JBQ2hDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFBO2lCQUMzQzthQUNGO1lBQ0QsZ0dBQWdHO1lBQ2hHLDZDQUE2QztZQUM3QyxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsVUFBVSxHQUFHLGFBQWEsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFBO1lBQ3BFLE9BQU8sQ0FBQyxvQkFBb0IsR0FBRyxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFBO1lBQ3ZFLE9BQU8sQ0FBQyxnQkFBZ0IsR0FBRyxPQUFPLENBQUMsb0JBQW9CLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLG9CQUFvQixHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtZQUMvRyxJQUFJLE9BQU8sQ0FBQyxvQkFBb0IsS0FBSyxHQUFHLElBQUksbUJBQW1CLElBQUksbUJBQW1CLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxDQUFDLHFCQUFxQixFQUFFO2dCQUM3SCxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLHdCQUF3QixDQUFDLE9BQU8sQ0FBQyxDQUFBO2dCQUN2RSxNQUFNLG1CQUFtQixHQUFHLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFPLEVBQUUsRUFBRSxDQUN6RCxFQUFFLENBQUMsWUFBWSxLQUFLLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUE7Z0JBQ3JELE1BQU0sVUFBVSxHQUFHLENBQUM7d0JBQ2xCLFNBQVMsRUFBRSxjQUFjLENBQUMsVUFBVTt3QkFDcEMsT0FBTyxFQUFFLG1CQUFtQixJQUFJLG1CQUFtQixDQUFDLE9BQU87d0JBQzNELGNBQWMsRUFBRSxDQUFDO3dCQUNqQixvQkFBb0IsRUFBRSxHQUFHO3dCQUN6QixRQUFRLEVBQUUsQ0FBQzt3QkFDWCxTQUFTLEVBQUUsQ0FBQzt3QkFDWixRQUFRLEVBQUUsbUJBQW1CLElBQUksbUJBQW1CLENBQUMsUUFBUTt3QkFDN0QsWUFBWSxFQUFFLG1CQUFtQixJQUFJLG1CQUFtQixDQUFDLFFBQVE7d0JBQ2pFLE1BQU0sRUFBRSxDQUFDO3FCQUNWLENBQUMsQ0FBQTtnQkFDRixtQkFBbUIsR0FBRyxVQUFVLENBQUE7Z0JBQ2hDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFBO2FBQzNDO1lBQ0QsY0FBYztZQUNkLHNFQUFzRTtZQUN0RSxPQUFPO1lBQ1AsS0FBSztZQUNMLHNEQUFzRDtZQUN0RCxJQUFJLENBQUMsMkJBQTJCLENBQUMsT0FBTyxDQUFDLENBQUE7WUFDekMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sQ0FBQyxDQUFBO1lBQ2pDLDZEQUE2RDtZQUM3RCxJQUFJLE9BQU8sQ0FBQyxjQUFjLEtBQUssa0JBQWtCLEVBQUU7Z0JBQ2pELElBQUksQ0FBQyw2QkFBNkIsRUFBRSxDQUFBO2dCQUNwQyw0REFBNEQ7Z0JBQzVELElBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQTthQUNuQztZQUNELElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO1NBQy9CO0lBQ0gsQ0FBQztJQUNELHVCQUF1QixDQUFDLFNBQWMsRUFBRSxjQUFtQjtRQUN6RCxJQUFJLGNBQWMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQzdCLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFRLEVBQUUsRUFBRTtnQkFDbEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxFQUFFO29CQUN0QyxTQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQTtpQkFDOUI7WUFDSCxDQUFDLENBQUMsQ0FBQTtTQUNIO0lBQ0gsQ0FBQztJQUVELGdFQUFnRTtJQUNoRSxpR0FBaUc7SUFDakcsNkRBQTZEO0lBQzdELHFFQUFxRTtJQUNyRSxJQUFJO0lBQ0osSUFBSTtJQUVKLDJCQUEyQixDQUFDLGFBQWtCLEVBQUUsVUFBa0I7UUFDaEUsT0FBTyxhQUFhLElBQUksYUFBYSxFQUFFLE1BQU0sSUFBSSxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBTyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsWUFBWSxLQUFLLFVBQVUsQ0FBQyxDQUFBO0lBQ25ILENBQUM7SUFFRCxLQUFLLENBQUMsbUNBQW1DLENBQUMsTUFBVztRQUNuRCxJQUFJLE1BQU0sSUFBSSxNQUFNLENBQUMsUUFBUSxFQUFFO1lBQzdCLE1BQU0sTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLFdBQWdCLEVBQUUsRUFBRTtnQkFDbkQsSUFBSSxDQUFDLFdBQVcsSUFBSSxXQUFXLENBQUMsUUFBUSxDQUFDLElBQUksV0FBVyxDQUFDLGVBQWUsS0FBSyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxFQUFFO29CQUM5RyxJQUFJLENBQUMsbUNBQW1DLENBQUMsV0FBVyxDQUFDLENBQUE7b0JBQ3JELE1BQU0sQ0FBQyxhQUFhLENBQUMsR0FBRyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtpQkFDOUU7cUJBQU07b0JBQ0wsV0FBVyxDQUFDLHNCQUFzQixDQUFDLEdBQUcsR0FBRyxDQUFBO29CQUN6QyxXQUFXLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLENBQUE7aUJBQ3BDO1lBQ0gsQ0FBQyxDQUFDLENBQUE7U0FDSDtJQUNILENBQUM7SUFFTSw0QkFBNEIsQ0FBQyxPQUFrQyxFQUFFLE1BQWlDO1FBQ3ZHLElBQUksT0FBTyxJQUFJLE9BQU8sQ0FBQyxRQUFRLEVBQUU7WUFDL0IsSUFBSSxPQUFPLENBQUMsZUFBZSxLQUFLLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUU7Z0JBQ2pFLHNEQUFzRDtnQkFDdEQsOEJBQThCO2dCQUM5QixPQUFPLEdBQUcsSUFBSSxDQUFDLDJCQUEyQixDQUFDLE9BQU8sQ0FBQyxDQUFBO2dCQUNuRCxLQUFLO2FBQ047WUFFRCxPQUFPLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQXdCLEVBQUUsRUFBRTtnQkFDaEQsb0VBQW9FO2dCQUNwRSxvREFBb0Q7Z0JBQ3BELFdBQVc7Z0JBQ1gsb0RBQW9EO2dCQUNwRCxJQUFJO2dCQUNKLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7b0JBQ3pCLElBQUksQ0FBQyw0QkFBNEIsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUE7aUJBQ2hEO1lBQ0gsQ0FBQyxDQUFDLENBQUE7U0FDSDtJQUNILENBQUM7SUFFTSw2QkFBNkIsQ0FBQyxhQUFpQyxFQUFFLGtCQUEyQjtRQUNqRyxJQUFJLGFBQWEsSUFBSSxhQUFhLENBQUMsUUFBUSxFQUFFO1lBQzNDLGFBQWEsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBeUIsRUFBRSxFQUFFO2dCQUMzRCxJQUFJLEtBQUssSUFBSSxLQUFLLENBQUMsUUFBUSxFQUFFO29CQUMzQixJQUFJLENBQUMsNkJBQTZCLENBQUMsS0FBSyxFQUFFLGtCQUFrQixDQUFDLENBQUE7aUJBQzlEO2dCQUNELE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxlQUF5QixDQUFBO2dCQUNsRCxNQUFNLFNBQVMsR0FBRyxDQUFDLEtBQUssQ0FBQyxjQUFjLElBQUksS0FBSyxDQUFDLGVBQWUsSUFBSSxFQUFFLENBQVcsQ0FBQTtnQkFDakYsTUFBTSxXQUFXLEdBQUcsVUFBVSxLQUFLLFdBQVcsSUFBSSxTQUFTLEtBQUssV0FBVyxDQUFBO2dCQUMzRSxNQUFNLFlBQVksR0FBRyxLQUFLLENBQUMsUUFBUSxLQUFLLFNBQVMsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFBO2dCQUN2RSxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsZUFBZSxLQUFLLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUE7Z0JBQzVFLE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLFFBQVE7b0JBQzlFLEtBQUssQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLGlCQUFpQjtvQkFDdEUsS0FBSyxDQUFDLGVBQWUsS0FBSyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsZ0JBQWdCO29CQUNyRSxLQUFLLENBQUMsZUFBZSxLQUFLLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxlQUFlLENBQUE7Z0JBQ3RFLE1BQU0saUJBQWlCLEdBQUcsa0JBQWtCLEtBQUssa0JBQWtCLENBQUE7Z0JBRW5FLHlFQUF5RTtnQkFDekUsTUFBTSxXQUFXLEdBQUcsS0FBSyxDQUFDLFdBQVcsS0FBSyxJQUFJLElBQUssS0FBYSxDQUFDLFNBQVMsS0FBSyxJQUFJLENBQUE7Z0JBRW5GLElBQUksUUFBUSxHQUFRO29CQUNsQixNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU07b0JBQ3JCLFVBQVUsRUFBRSxLQUFLLENBQUMsVUFBVTtvQkFDNUIsY0FBYyxFQUFFLEtBQUssQ0FBQyxjQUFjLElBQUksSUFBSTtvQkFDNUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxTQUFTLElBQUksRUFBRTtvQkFDaEMsb0JBQW9CLEVBQUUsS0FBSyxDQUFDLG9CQUFvQixJQUFJLEtBQUssQ0FBQyxRQUFRLElBQUksQ0FBQztvQkFDdkUsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLGdCQUFnQixJQUFJLEtBQUssQ0FBQyxNQUFNLElBQUksQ0FBQztvQkFDN0QsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNLElBQUksS0FBSyxDQUFDLGdCQUFnQixJQUFJLENBQUM7b0JBQ25ELFFBQVEsRUFBRSxLQUFLLENBQUMsUUFBUTtvQkFDeEIsZUFBZSxFQUFFLEtBQUssQ0FBQyxlQUFlO29CQUN0QyxjQUFjLEVBQUUsU0FBUztvQkFDekIsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRLElBQUksQ0FBQztvQkFDN0IsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLGdCQUFnQixJQUFJLENBQUM7b0JBQzdDLG1EQUFtRDtvQkFDbkQsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRO29CQUN4QixRQUFRLEVBQUUsS0FBSyxDQUFDLFFBQVEsSUFBSSxLQUFLO29CQUNqQyxXQUFXLEVBQUUsS0FBSyxDQUFDLFdBQVcsSUFBSSxJQUFJO29CQUN0QyxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUksSUFBSSxFQUFFO29CQUN0QixXQUFXLEVBQUUsS0FBSyxDQUFDLFdBQVcsSUFBSSxFQUFFO29CQUNwQywwQ0FBMEM7b0JBQzFDLFdBQVcsRUFBRSxXQUFXO29CQUN4QixZQUFZLEVBQUUsWUFBWTtvQkFDMUIsUUFBUSxFQUFFLFFBQVE7b0JBQ2xCLFVBQVUsRUFBRSxVQUFVO29CQUN0QixpQkFBaUIsRUFBRSxpQkFBaUI7b0JBQ3BDLFdBQVcsRUFBRSxXQUFXO29CQUN4QiwwQkFBMEI7b0JBQzFCLGNBQWMsRUFBRyxLQUFhLENBQUMsY0FBYztvQkFDN0MsdUJBQXVCLEVBQUcsS0FBYSxDQUFDLHVCQUF1QixJQUFJLENBQUM7b0JBQ3BFLDZDQUE2QztvQkFDN0MsZUFBZSxFQUFHLEtBQWEsQ0FBQyxlQUFlLElBQUksS0FBSztpQkFDekQsQ0FBQTtnQkFFRCwrQkFBK0I7Z0JBQy9CLElBQUksV0FBVyxFQUFFO29CQUNmLGlDQUFpQztpQkFDbEM7Z0JBRUQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEdBQUcsUUFBUSxDQUFBO1lBQzNDLENBQUMsQ0FBQyxDQUFBO1NBQ0g7SUFDSCxDQUFDO0lBRU0sMENBQTBDLENBQUMsYUFBaUM7UUFDakYsSUFBSSxhQUFhLElBQUksYUFBYSxDQUFDLHFCQUFxQixFQUFFO1lBQ3hELGFBQWEsQ0FBQyxxQkFBcUIsQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUF5QixFQUFFLEVBQUU7Z0JBQ3hFLElBQUksS0FBSyxJQUFJLEtBQUssQ0FBQyxxQkFBcUIsRUFBRTtvQkFDeEMsSUFBSSxDQUFDLDBDQUEwQyxDQUFDLEtBQUssQ0FBQyxDQUFBO2lCQUN2RDtnQkFDRCxJQUFJLFFBQVEsR0FBRyxFQUFFLENBQUE7Z0JBQ2pCLFFBQVEsR0FBRztvQkFDVCxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU07b0JBQ3JCLFVBQVUsRUFBRSxLQUFLLENBQUMsVUFBVTtvQkFDNUIsY0FBYyxFQUFFLEtBQUssQ0FBQyxjQUFjLElBQUksSUFBSTtvQkFDNUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxTQUFTLElBQUksRUFBRTtvQkFDaEMsb0JBQW9CLEVBQUUsS0FBSyxDQUFDLG9CQUFvQixJQUFJLEtBQUssQ0FBQyxRQUFRO29CQUNsRSxnQkFBZ0IsRUFBRSxLQUFLLENBQUMsZ0JBQWdCO29CQUN4QyxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0JBQWdCLElBQUksQ0FBQztvQkFDbkQsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRO29CQUN4QixlQUFlLEVBQUUsS0FBSyxDQUFDLGVBQWU7b0JBQ3RDLGNBQWMsRUFBRSxLQUFLLENBQUMsY0FBYyxJQUFJLEtBQUssQ0FBQyxlQUFlLElBQUksRUFBRTtvQkFDbkUsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRLElBQUksQ0FBQztvQkFDN0IsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLGdCQUFnQixJQUFJLENBQUM7b0JBQzdDLHlFQUF5RTtvQkFDekUsZUFBZSxFQUFFLEtBQUssQ0FBQyxlQUFlLElBQUksS0FBSztpQkFDaEQsQ0FBQTtnQkFDRCxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsR0FBRyxRQUFRLENBQUE7WUFDM0MsQ0FBQyxDQUFDLENBQUE7U0FDSDtJQUNILENBQUM7SUFFTSwyQkFBMkIsQ0FBQyxhQUF3QztRQUN6RSxJQUFJLGFBQWEsRUFBRTtZQUNqQixNQUFNLGtCQUFrQixHQUFHLGFBQWEsQ0FBQyxjQUFjLElBQUksYUFBYSxDQUFDLGVBQWUsSUFBSSxFQUFFLENBQUE7WUFDOUYsTUFBTSxpQkFBaUIsR0FBRyxrQkFBa0IsS0FBSyxrQkFBa0IsQ0FBQTtZQUVuRSxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsR0FBRztnQkFDdkMsTUFBTSxFQUFFLGFBQWEsQ0FBQyxNQUFNO2dCQUM1QixVQUFVLEVBQUUsYUFBYSxDQUFDLFVBQVU7Z0JBQ3BDLGNBQWMsRUFBRSxhQUFhLENBQUMsY0FBYyxJQUFJLElBQUk7Z0JBQ3BELFNBQVMsRUFBRSxhQUFhLENBQUMsU0FBUyxJQUFJLEVBQUU7Z0JBQ3hDLG9CQUFvQixFQUFFLGFBQWEsQ0FBQyxvQkFBb0IsSUFBSSxhQUFhLENBQUMsUUFBUSxJQUFJLENBQUM7Z0JBQ3ZGLGdCQUFnQixFQUFFLGFBQWEsQ0FBQyxnQkFBZ0IsSUFBSSxDQUFDO2dCQUNyRCxRQUFRLEVBQUUsYUFBYSxDQUFDLFFBQVE7Z0JBQ2hDLGVBQWUsRUFBRSxhQUFhLENBQUMsZUFBZTtnQkFDOUMsY0FBYyxFQUFFLGtCQUFrQjtnQkFDbEMsZ0JBQWdCLEVBQUUsYUFBYSxDQUFDLGdCQUFnQixJQUFJLENBQUM7Z0JBQ3JELHNCQUFzQjtnQkFDdEIsUUFBUSxFQUFFLGFBQWEsQ0FBQyxRQUFRO2dCQUNoQyxRQUFRLEVBQUUsYUFBYSxDQUFDLFFBQVEsSUFBSSxLQUFLO2dCQUN6QyxXQUFXLEVBQUUsYUFBYSxDQUFDLFdBQVcsSUFBSSxJQUFJO2dCQUM5QyxJQUFJLEVBQUUsYUFBYSxDQUFDLElBQUksSUFBSSxFQUFFO2dCQUM5QixXQUFXLEVBQUUsYUFBYSxDQUFDLFdBQVcsSUFBSSxFQUFFO2dCQUM1QyxXQUFXLEVBQUUsS0FBSztnQkFDbEIsWUFBWSxFQUFFLGFBQWEsQ0FBQyxRQUFRLEtBQUssU0FBUyxDQUFDLFVBQVUsQ0FBQyxVQUFVO2dCQUN4RSxRQUFRLEVBQUUsYUFBYSxDQUFDLGVBQWUsS0FBSyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsTUFBTTtnQkFDN0UsVUFBVSxFQUFFLEtBQUs7Z0JBQ2pCLGlCQUFpQixFQUFFLGlCQUFpQjthQUNyQyxDQUFBO1lBQ0QsSUFBSSxhQUFhLENBQUMsZUFBZSxLQUFLLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxlQUFlO2dCQUM5RSxhQUFhLENBQUMsa0JBQWtCLElBQUksQ0FBQyxJQUFJLGFBQWEsQ0FBQyxrQkFBa0I7Z0JBQ3pFLGFBQWEsQ0FBQyxrQkFBa0IsS0FBSyxTQUFTLENBQUMsbUJBQW1CLENBQUMsc0JBQXNCLEVBQUU7Z0JBQzNGLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxHQUFHO29CQUN2QyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQztvQkFDekMsa0JBQWtCLEVBQUUsYUFBYSxDQUFDLGtCQUFrQjtvQkFDcEQsa0JBQWtCLEVBQUUsYUFBYSxDQUFDLGtCQUFrQjtpQkFDckQsQ0FBQTthQUNGO1lBQ0QsSUFBSSxDQUFDLDZCQUE2QixDQUFDLGFBQWEsRUFBRSxrQkFBa0IsQ0FBQyxDQUFBO1lBQ3JFLGlGQUFpRjtZQUNqRiwrRUFBK0U7WUFDL0UsSUFBSSxDQUFDLE9BQU8sR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFBO1NBQ25DO0lBQ0gsQ0FBQztJQUVEOzs7Ozs7Ozs7OztPQVdHO0lBQ0g7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQXVDRztJQUNJLDZCQUE2QixDQUFDLGFBQXNCLElBQUk7UUFDN0QsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtZQUMzRCxPQUFPLENBQUMsSUFBSSxDQUFDLHlEQUF5RCxDQUFDLENBQUE7WUFDdkUsT0FBTTtTQUNQO1FBRUQsT0FBTyxDQUFDLEdBQUcsQ0FBQywrREFBK0QsQ0FBQyxDQUFBO1FBQzVFLE9BQU8sQ0FBQyxHQUFHLENBQUMsd0NBQXdDLENBQUMsQ0FBQTtRQUNyRCxPQUFPLENBQUMsR0FBRyxDQUFDLDZEQUE2RCxDQUFDLENBQUE7UUFDMUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsRUFBRSxVQUFVLENBQUMsQ0FBQTtRQUN6QyxPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUU5RCxnREFBZ0Q7UUFDaEQsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7YUFDL0MsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQ1osTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUM5QixPQUFPLElBQUksQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFDLGVBQWUsS0FBSyxXQUFXLElBQUksSUFBSSxDQUFDLGNBQWMsS0FBSyxXQUFXLENBQUE7UUFDeEcsQ0FBQyxDQUFDO2FBQ0QsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ2IsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQTtZQUM3QixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFBO1lBQzdCLElBQUksS0FBSyxDQUFDLGNBQWMsS0FBSyxTQUFTLElBQUksS0FBSyxDQUFDLGNBQWMsS0FBSyxTQUFTLEVBQUU7Z0JBQzVFLE9BQU8sS0FBSyxDQUFDLGNBQWMsR0FBRyxLQUFLLENBQUMsY0FBYyxDQUFBO2FBQ25EO1lBQ0QsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFBO1lBQ2hELE1BQU0sSUFBSSxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQTtZQUNoRCxPQUFPLElBQUksR0FBRyxJQUFJLENBQUE7UUFDcEIsQ0FBQyxDQUFDLENBQUE7UUFFSixJQUFJLGdCQUFnQixDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7WUFDakMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxzREFBc0QsQ0FBQyxDQUFBO1lBQ25FLE9BQU8sQ0FBQyxHQUFHLENBQUMsK0RBQStELENBQUMsQ0FBQTtZQUM1RSxPQUFNO1NBQ1A7UUFFRCxPQUFPLENBQUMsR0FBRyxDQUFDLGNBQWMsZ0JBQWdCLENBQUMsTUFBTSxjQUFjLENBQUMsQ0FBQTtRQUNoRSxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDakMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQTtRQUM3RCxDQUFDLENBQUMsQ0FBQTtRQUVGLGlFQUFpRTtRQUNqRSxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQ2YsT0FBTyxDQUFDLEdBQUcsQ0FBQywrREFBK0QsQ0FBQyxDQUFBO1lBQzVFLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsRUFBRTtnQkFDckMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUE7Z0JBQ2pELElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMsYUFBYSxHQUFHLDRDQUE0QyxDQUFBO1lBQ3hGLENBQUMsQ0FBQyxDQUFBO1lBQ0Ysb0JBQW9CO1lBQ3BCLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRTtnQkFDdEMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsV0FBVyxFQUFFO29CQUNsQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLHVCQUF1QixHQUFHLElBQUksQ0FBQTtpQkFDakQ7WUFDSCxDQUFDLENBQUMsQ0FBQTtZQUNGLElBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQTtZQUNsQyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFBO1lBQzFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsK0RBQStELENBQUMsQ0FBQTtZQUM1RSxPQUFNO1NBQ1A7UUFFRCwwQ0FBMEM7UUFDMUMsTUFBTSx3QkFBd0IsR0FBRyxJQUFJLENBQUMsNEJBQTRCLEVBQUUsQ0FBQTtRQUNwRSxPQUFPLENBQUMsR0FBRyxDQUFDLHdCQUF3Qix3QkFBd0IsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFBO1FBRS9GLDZDQUE2QztRQUM3QyxPQUFPLENBQUMsR0FBRyxDQUFDLGlDQUFpQyxDQUFDLENBQUE7UUFDOUMsT0FBTyxDQUFDLEdBQUcsQ0FBQywrREFBK0QsQ0FBQyxDQUFBO1FBRTVFLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDLFdBQVcsRUFBRSxLQUFLLEVBQUUsRUFBRTtZQUM5QyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFBO1lBQzNDLElBQUksQ0FBQyxTQUFTO2dCQUFFLE9BQU07WUFFdEIsTUFBTSxZQUFZLEdBQUcsS0FBSyxHQUFHLENBQUMsQ0FBQTtZQUM5QixPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixZQUFZLEtBQUssU0FBUyxDQUFDLElBQUksSUFBSSxXQUFXLElBQUksQ0FBQyxDQUFBO1lBRWpGLG9EQUFvRDtZQUNwRCxJQUFJLEtBQUssS0FBSyxDQUFDLEVBQUU7Z0JBQ2YsTUFBTSxRQUFRLEdBQUcsQ0FBQyx3QkFBd0IsQ0FBQTtnQkFDMUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQyxnQkFBZ0IsR0FBRyxRQUFRLENBQUE7Z0JBQ3JELElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMsYUFBYSxHQUFHLFFBQVEsQ0FBQyxDQUFDO29CQUNsRCw4REFBOEQsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFBO2dCQUVyRSxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sUUFBUSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUE7Z0JBQzNELE9BQU8sQ0FBQyxHQUFHLENBQUMsNkJBQTZCLHdCQUF3QixDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUE7Z0JBRWhHLDRDQUE0QztnQkFDNUMsSUFBSSxDQUFDLFFBQVEsRUFBRTtvQkFDYixPQUFPLENBQUMsR0FBRyxDQUFDLGtDQUFrQyxDQUFDLENBQUE7b0JBQy9DLElBQUksQ0FBQyxtQ0FBbUMsQ0FBQyxXQUFXLENBQUMsQ0FBQTtpQkFDdEQ7cUJBQU07b0JBQ0wsT0FBTyxDQUFDLEdBQUcsQ0FBQywrREFBK0QsQ0FBQyxDQUFBO29CQUM1RSxJQUFJLENBQUMsbUNBQW1DLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxDQUFBO2lCQUM1RDtnQkFDRCxPQUFNO2FBQ1A7WUFFRCxnRUFBZ0U7WUFDaEUsTUFBTSxtQkFBbUIsR0FBRyxnQkFBZ0IsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUE7WUFDdkQsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLG1CQUFtQixDQUFDLENBQUE7WUFFM0QsSUFBSSxpQkFBaUIsRUFBRTtnQkFDckIsMkNBQTJDO2dCQUMzQyxNQUFNLGlCQUFpQixHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsQ0FBQTtnQkFDN0UsTUFBTSxvQkFBb0IsR0FBRyxNQUFNLENBQUMsaUJBQWlCLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUE7Z0JBQzVFLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUE7Z0JBQ3hELE1BQU0sc0JBQXNCLEdBQUcsTUFBTSxDQUFDLGlCQUFpQixDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxDQUFBO2dCQUNyRixNQUFNLGtCQUFrQixHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUE7Z0JBRXhFLElBQUkseUJBQXlCLEdBQzNCLGlCQUFpQixJQUFJLEdBQUc7b0JBQ3hCLG9CQUFvQixLQUFLLENBQUM7b0JBQzFCLFVBQVUsS0FBSyxDQUFDO29CQUNoQixDQUFDLGtCQUFrQixHQUFHLENBQUMsSUFBSSxzQkFBc0IsSUFBSSxrQkFBa0IsQ0FBQyxDQUFBO2dCQUUxRSxtQ0FBbUM7Z0JBQ25DLElBQUksQ0FBQyx5QkFBeUIsRUFBRTtvQkFDOUIsTUFBTSxxQ0FBcUMsR0FBRyxJQUFJLENBQUMsZ0NBQWdDLENBQUMsbUJBQW1CLENBQUMsQ0FBQTtvQkFDeEcsTUFBTSxvQ0FBb0MsR0FBRyxJQUFJLENBQUMsc0NBQXNDLENBQUMsbUJBQW1CLENBQUMsQ0FBQTtvQkFDN0cseUJBQXlCLEdBQUcscUNBQXFDLElBQUksb0NBQW9DLENBQUE7b0JBQ3pHLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0NBQWdDLG9DQUFvQyxnQkFBZ0IscUNBQXFDLEVBQUUsQ0FBQyxDQUFBO2lCQUN6STtnQkFFRCxNQUFNLFFBQVEsR0FBRyxDQUFDLHlCQUF5QixDQUFBO2dCQUMzQyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDLGdCQUFnQixHQUFHLFFBQVEsQ0FBQTtnQkFDckQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQyxhQUFhLEdBQUcsUUFBUSxDQUFDLENBQUM7b0JBQ2xELDhEQUE4RCxLQUFLLDJCQUEyQixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUE7Z0JBRXJHLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxRQUFRLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsYUFBYSxFQUFFLENBQUMsQ0FBQTtnQkFDM0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQ0FBaUMseUJBQXlCLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQTtnQkFDckcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsS0FBSyxjQUFjLGlCQUFpQixHQUFHLENBQUMsQ0FBQTtnQkFFcEUsb0RBQW9EO2dCQUNwRCxJQUFJLENBQUMsUUFBUSxFQUFFO29CQUNiLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0NBQWtDLENBQUMsQ0FBQTtvQkFDL0MsSUFBSSxDQUFDLG1DQUFtQyxDQUFDLFdBQVcsQ0FBQyxDQUFBO2lCQUN0RDtxQkFBTTtvQkFDTCxPQUFPLENBQUMsR0FBRyxDQUFDLCtEQUErRCxDQUFDLENBQUE7b0JBQzVFLElBQUksQ0FBQyxtQ0FBbUMsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLENBQUE7aUJBQzVEO2FBQ0Y7aUJBQU07Z0JBQ0wsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUE7Z0JBQ2pELElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMsYUFBYSxHQUFHLDhCQUE4QixDQUFBO2dCQUN4RSxPQUFPLENBQUMsR0FBRyxDQUFDLDZDQUE2QyxDQUFDLENBQUE7YUFDM0Q7UUFDSCxDQUFDLENBQUMsQ0FBQTtRQUVGLGdFQUFnRTtRQUNoRSxPQUFPLENBQUMsR0FBRyxDQUFDLDJEQUEyRCxDQUFDLENBQUE7UUFDeEUsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQ3RDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUE7WUFDOUIsSUFBSSxJQUFJLENBQUMsV0FBVztnQkFBRSxPQUFNLENBQUMsNkJBQTZCO1lBRTFELDBEQUEwRDtZQUMxRCxJQUFJLGVBQWUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFBO1lBQ2pDLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQTtZQUNiLE1BQU0sUUFBUSxHQUFHLENBQUMsQ0FBQTtZQUNsQixJQUFJLGlCQUFpQixHQUFHLEtBQUssQ0FBQTtZQUU3QixPQUFPLGVBQWUsSUFBSSxLQUFLLEdBQUcsUUFBUSxFQUFFO2dCQUMxQyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxDQUFBO2dCQUNoRCxJQUFJLFVBQVUsRUFBRTtvQkFDZCxJQUFJLFVBQVUsQ0FBQyxXQUFXLElBQUksVUFBVSxDQUFDLGdCQUFnQixFQUFFO3dCQUN6RCxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLHVCQUF1QixHQUFHLElBQUksQ0FBQTt3QkFDaEQsaUJBQWlCLEdBQUcsSUFBSSxDQUFBO3dCQUN4QixNQUFLO3FCQUNOO29CQUNELGVBQWUsR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFBO2lCQUNwQztxQkFBTTtvQkFDTCxNQUFLO2lCQUNOO2dCQUNELEtBQUssRUFBRSxDQUFBO2FBQ1I7WUFFRCxJQUFJLENBQUMsaUJBQWlCLEVBQUU7Z0JBQ3RCLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsdUJBQXVCLEdBQUcsS0FBSyxDQUFBO2FBQ2xEO1FBQ0gsQ0FBQyxDQUFDLENBQUE7UUFFRixpQ0FBaUM7UUFDakMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpRUFBaUUsQ0FBQyxDQUFBO1FBQzlFLE9BQU8sQ0FBQyxHQUFHLENBQUMsMENBQTBDLENBQUMsQ0FBQTtRQUN2RCxPQUFPLENBQUMsR0FBRyxDQUFDLCtEQUErRCxDQUFDLENBQUE7UUFFNUUsSUFBSSxDQUFDLE9BQU8sR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFBO1FBQ2xDLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUE7SUFDNUUsQ0FBQztJQUVEOzs7T0FHRztJQUNJLDBCQUEwQjtRQUMvQixxREFBcUQ7UUFDckQsTUFBTSxrQkFBa0IsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDOUQsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUM5QixPQUFPLElBQUksQ0FBQyxpQkFBaUIsSUFBSSxJQUFJLENBQUMsY0FBYyxLQUFLLGtCQUFrQixDQUFBO1FBQzdFLENBQUMsQ0FBQyxDQUFBO1FBRUYsSUFBSSxrQkFBa0IsRUFBRTtZQUN0QixPQUFPLENBQUMsR0FBRyxDQUFDLGtFQUFrRSxDQUFDLENBQUE7WUFDL0Usa0RBQWtEO1lBQ2xELElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxJQUFJLENBQUMsQ0FBQTtTQUN6QztJQUNILENBQUM7SUFFRDs7O09BR0c7SUFDSyw0QkFBNEI7UUFDbEMsaUNBQWlDO1FBQ2pDLElBQUksaUJBQWlCLEdBQWtCLElBQUksQ0FBQTtRQUMzQyxLQUFLLE1BQU0sR0FBRyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQzNDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUE7WUFDOUIsSUFBSSxJQUFJLENBQUMsaUJBQWlCLElBQUksSUFBSSxDQUFDLGNBQWMsS0FBSyxrQkFBa0IsRUFBRTtnQkFDeEUsaUJBQWlCLEdBQUcsR0FBRyxDQUFBO2dCQUN2QixNQUFLO2FBQ047U0FDRjtRQUVELE9BQU8sQ0FBQyxHQUFHLENBQUMsMERBQTBELEVBQUUsaUJBQWlCLENBQUMsQ0FBQTtRQUUxRixpRUFBaUU7UUFDakUsS0FBSyxNQUFNLEdBQUcsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRTtZQUMzQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFBO1lBQzlCLElBQUksSUFBSSxDQUFDLGVBQWUsS0FBSyxJQUFJLEVBQUU7Z0JBQ2pDLHdEQUF3RDtnQkFDeEQsTUFBTSxXQUFXLEdBQUcsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQztvQkFDakQsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLEtBQUssU0FBUyxJQUFJLElBQUksQ0FBQyxvQkFBb0IsSUFBSSxHQUFHLENBQUM7b0JBQzdFLENBQUMsSUFBSSxDQUFDLFFBQVEsS0FBSyxTQUFTLElBQUksSUFBSSxDQUFDLFFBQVEsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFBO2dCQUMxRSxPQUFPLENBQUMsR0FBRyxDQUFDLGtEQUFrRCxHQUFHLEVBQUUsRUFBRTtvQkFDbkUsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO29CQUNmLGdCQUFnQixFQUFFLElBQUksQ0FBQyxnQkFBZ0I7b0JBQ3ZDLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTTtvQkFDbkIsb0JBQW9CLEVBQUUsSUFBSSxDQUFDLG9CQUFvQjtvQkFDL0MsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO29CQUN2QixXQUFXO29CQUNYLDRDQUE0QztvQkFDNUMsT0FBTyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7aUJBQ3ZDLENBQUMsQ0FBQTtnQkFDRixvRUFBb0U7Z0JBQ3BFLE9BQU8sV0FBVyxDQUFBO2FBQ25CO1NBQ0Y7UUFFRCx3R0FBd0c7UUFDeEcsMERBQTBEO1FBQzFELEtBQUssTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUU7WUFDM0MsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUU5QiwwREFBMEQ7WUFDMUQsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLGlCQUFpQjtnQkFBRSxTQUFRO1lBRS9DLGtCQUFrQjtZQUNsQixJQUFJLElBQUksQ0FBQyxXQUFXO2dCQUFFLFNBQVE7WUFFOUIsaUVBQWlFO1lBQ2pFLHdEQUF3RDtZQUN4RCxNQUFNLFdBQVcsR0FBRyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDO2dCQUNqRCxDQUFDLElBQUksQ0FBQyxvQkFBb0IsS0FBSyxTQUFTLElBQUksSUFBSSxDQUFDLG9CQUFvQixJQUFJLEdBQUcsQ0FBQztnQkFDN0UsQ0FBQyxJQUFJLENBQUMsUUFBUSxLQUFLLFNBQVMsSUFBSSxJQUFJLENBQUMsUUFBUSxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUE7WUFDMUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyx1REFBdUQsR0FBRyxFQUFFLEVBQUU7Z0JBQ3hFLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSTtnQkFDZixnQkFBZ0IsRUFBRSxJQUFJLENBQUMsZ0JBQWdCO2dCQUN2QyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU07Z0JBQ25CLG9CQUFvQixFQUFFLElBQUksQ0FBQyxvQkFBb0I7Z0JBQy9DLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtnQkFDdkIsV0FBVztnQkFDWCw0Q0FBNEM7Z0JBQzVDLE9BQU8sRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO2FBQ3ZDLENBQUMsQ0FBQTtZQUNGLG9FQUFvRTtZQUNwRSxPQUFPLFdBQVcsQ0FBQTtTQUNuQjtRQUVELHlFQUF5RTtRQUN6RSwwQkFBMEI7UUFDMUIsdURBQXVEO1FBQ3ZELGdGQUFnRjtRQUVoRixpREFBaUQ7UUFDakQsTUFBTSxjQUFjLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQzFELElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxLQUFLLGlCQUFpQixDQUMvQyxDQUFBO1FBRUQsSUFBSSxDQUFDLGNBQWMsRUFBRTtZQUNuQiwwREFBMEQ7WUFDMUQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxzRUFBc0UsQ0FBQyxDQUFBO1lBQ25GLE9BQU8sS0FBSyxDQUFBO1NBQ2I7UUFFRCx3RUFBd0U7UUFDeEUsT0FBTyxDQUFDLEdBQUcsQ0FBQyw0RkFBNEYsQ0FBQyxDQUFBO1FBQ3pHLE9BQU8sSUFBSSxDQUFBO0lBQ2IsQ0FBQztJQUVEOzs7T0FHRztJQUNLLGdDQUFnQyxDQUFDLFdBQW1CO1FBQzFELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUE7UUFFM0MsK0VBQStFO1FBQy9FLEtBQUssTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUU7WUFDM0MsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUU5QixzQ0FBc0M7WUFDdEMsTUFBTSxnQkFBZ0IsR0FDcEIsSUFBSSxDQUFDLGVBQWUsS0FBSyxtQkFBbUI7Z0JBQzVDLElBQUksQ0FBQyxlQUFlLEtBQUssa0JBQWtCO2dCQUMzQyxJQUFJLENBQUMsZUFBZSxLQUFLLHVCQUF1QjtnQkFDaEQsSUFBSSxDQUFDLGNBQWMsS0FBSyxtQkFBbUI7Z0JBQzNDLElBQUksQ0FBQyxjQUFjLEtBQUssa0JBQWtCO2dCQUMxQyxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQTtZQUUvRCxJQUFJLENBQUMsZ0JBQWdCO2dCQUFFLFNBQVE7WUFFL0IscURBQXFEO1lBQ3JELElBQUksSUFBSSxDQUFDLGtCQUFrQixDQUFDLEdBQUcsRUFBRSxXQUFXLENBQUMsRUFBRTtnQkFDN0MsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsb0JBQW9CLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLElBQUksR0FBRyxDQUFBO2dCQUNoSSxJQUFJLFdBQVcsRUFBRTtvQkFDZixPQUFPLElBQUksQ0FBQTtpQkFDWjthQUNGO1NBQ0Y7UUFFRCwrRUFBK0U7UUFDL0UsT0FBTyxJQUFJLENBQUE7SUFDYixDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssc0NBQXNDLENBQUMsV0FBbUI7UUFDaEUsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQTtRQUUzQyxJQUFJLGNBQWMsR0FBRyxDQUFDLENBQUE7UUFDdEIsSUFBSSx1QkFBdUIsR0FBRyxDQUFDLENBQUE7UUFFL0Isa0ZBQWtGO1FBQ2xGLEtBQUssTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUU7WUFDM0MsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUU5Qix1RUFBdUU7WUFDdkUsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLFdBQVc7Z0JBQUUsU0FBUTtZQUV6QyxxQ0FBcUM7WUFDckMsSUFBSSxJQUFJLENBQUMsZUFBZSxLQUFLLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZO2dCQUFFLFNBQVE7WUFFckUsZ0RBQWdEO1lBQ2hELE1BQU0sWUFBWSxHQUNoQixJQUFJLENBQUMsZUFBZSxLQUFLLG1CQUFtQjtnQkFDNUMsSUFBSSxDQUFDLGVBQWUsS0FBSyxrQkFBa0I7Z0JBQzNDLElBQUksQ0FBQyxjQUFjLEtBQUssbUJBQW1CO2dCQUMzQyxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQTtZQUMvRCxJQUFJLFlBQVk7Z0JBQUUsU0FBUTtZQUUxQixxQ0FBcUM7WUFDckMsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFO2dCQUNwQixjQUFjLEVBQUUsQ0FBQTtnQkFDaEIsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsb0JBQW9CLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLElBQUksR0FBRyxDQUFBO2dCQUNoSSxJQUFJLFdBQVcsRUFBRTtvQkFDZix1QkFBdUIsRUFBRSxDQUFBO2lCQUMxQjthQUNGO1NBQ0Y7UUFFRCxNQUFNLFdBQVcsR0FBRyxjQUFjLEtBQUssQ0FBQyxJQUFJLHVCQUF1QixJQUFJLGNBQWMsQ0FBQTtRQUNyRixPQUFPLFdBQVcsQ0FBQTtJQUNwQixDQUFDO0lBRUQ7O09BRUc7SUFDSyxrQkFBa0IsQ0FBQyxTQUFpQixFQUFFLFdBQW1CO1FBQy9ELElBQUksU0FBUyxHQUFHLFNBQVMsQ0FBQTtRQUN6QixJQUFJLEtBQUssR0FBRyxDQUFDLENBQUE7UUFDYixNQUFNLFFBQVEsR0FBRyxFQUFFLENBQUE7UUFFbkIsT0FBTyxTQUFTLElBQUksS0FBSyxHQUFHLFFBQVEsRUFBRTtZQUNwQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFBO1lBQ3BDLElBQUksQ0FBQyxJQUFJO2dCQUFFLE9BQU8sS0FBSyxDQUFBO1lBQ3ZCLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxXQUFXO2dCQUFFLE9BQU8sSUFBSSxDQUFBO1lBQzVDLFNBQVMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFBO1lBQ3ZCLEtBQUssRUFBRSxDQUFBO1NBQ1I7UUFDRCxPQUFPLEtBQUssQ0FBQTtJQUNkLENBQUM7SUFFRDs7O09BR0c7SUFDSyxtQ0FBbUMsQ0FBQyxXQUFtQjtRQUM3RCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFBO1FBQzNDLElBQUksQ0FBQyxTQUFTO1lBQUUsT0FBTTtRQUV0QixPQUFPLENBQUMsR0FBRyxDQUFDLCtDQUErQyxXQUFXLEVBQUUsQ0FBQyxDQUFBO1FBRXpFLG9DQUFvQztRQUNwQyxJQUFJLFlBQVksR0FBa0IsSUFBSSxDQUFBO1FBQ3RDLElBQUksVUFBVSxHQUFRLElBQUksQ0FBQTtRQUUxQixLQUFLLE1BQU0sR0FBRyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQzNDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUE7WUFFOUIsZ0VBQWdFO1lBQ2hFLG9FQUFvRTtZQUNwRSxNQUFNLFlBQVksR0FBRyxDQUNuQixJQUFJLENBQUMsZUFBZSxLQUFLLG1CQUFtQjtnQkFDNUMsSUFBSSxDQUFDLGVBQWUsS0FBSyxrQkFBa0I7Z0JBQzNDLElBQUksQ0FBQyxlQUFlLEtBQUssdUJBQXVCO2dCQUNoRCxJQUFJLENBQUMsUUFBUSxLQUFLLHFDQUFxQztnQkFDdkQsSUFBSSxDQUFDLFFBQVEsS0FBSyxrQkFBa0IsQ0FDckMsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLFdBQVcsQ0FBQSxDQUFFLG9DQUFvQztZQUV0RSxJQUFJLFlBQVksRUFBRTtnQkFDaEIsWUFBWSxHQUFHLEdBQUcsQ0FBQTtnQkFDbEIsVUFBVSxHQUFHLElBQUksQ0FBQTtnQkFDakIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQ0FBaUMsSUFBSSxDQUFDLElBQUksS0FBSyxHQUFHLEdBQUcsQ0FBQyxDQUFBO2dCQUNsRSxNQUFLO2FBQ047U0FDRjtRQUVELElBQUksQ0FBQyxZQUFZLElBQUksQ0FBQyxVQUFVLEVBQUU7WUFDaEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxvQ0FBb0MsV0FBVyxFQUFFLENBQUMsQ0FBQTtZQUM5RCxPQUFNO1NBQ1A7UUFFRCxxRkFBcUY7UUFDckYsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQUFBO1FBQ25ELE1BQU0sbUJBQW1CLEdBQ3ZCLGdCQUFnQixDQUFDLGdCQUFnQixLQUFLLENBQUM7WUFDdkMsZ0JBQWdCLENBQUMsTUFBTSxLQUFLLENBQUM7WUFDN0IsZ0JBQWdCLENBQUMsb0JBQW9CLElBQUksR0FBRyxDQUFBO1FBRTlDLElBQUksbUJBQW1CLEVBQUU7WUFDdkIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQyxrQkFBa0IsR0FBRyxLQUFLLENBQUE7WUFDckQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQyxxQkFBcUIsR0FBRyxFQUFFLENBQUE7WUFDckQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLFlBQVksMkJBQTJCLENBQUMsQ0FBQTtZQUNsRSxPQUFNO1NBQ1A7UUFFRCxxREFBcUQ7UUFDckQsSUFBSSxjQUFjLEdBQUcsQ0FBQyxDQUFBO1FBQ3RCLElBQUksdUJBQXVCLEdBQUcsQ0FBQyxDQUFBO1FBRS9CLEtBQUssTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUU7WUFDM0MsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUU5Qiw2QkFBNkI7WUFDN0IsSUFBSSxHQUFHLEtBQUssWUFBWTtnQkFBRSxTQUFRO1lBRWxDLDBDQUEwQztZQUMxQyxJQUFJLGtCQUFrQixHQUFHLEtBQUssQ0FBQTtZQUM5QixJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssV0FBVyxFQUFFO2dCQUMvQixrQkFBa0IsR0FBRyxJQUFJLENBQUE7YUFDMUI7aUJBQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFO2dCQUNuRCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQTtnQkFDNUMsSUFBSSxVQUFVLENBQUMsTUFBTSxLQUFLLFdBQVcsSUFBSSxVQUFVLENBQUMsZUFBZSxLQUFLLFFBQVEsRUFBRTtvQkFDaEYsa0JBQWtCLEdBQUcsSUFBSSxDQUFBO2lCQUMxQjthQUNGO1lBRUQsSUFBSSxDQUFDLGtCQUFrQjtnQkFBRSxTQUFRO1lBRWpDLDBEQUEwRDtZQUMxRCxNQUFNLGdCQUFnQixHQUNwQixJQUFJLENBQUMsZUFBZSxLQUFLLG1CQUFtQjtnQkFDNUMsSUFBSSxDQUFDLGVBQWUsS0FBSyxrQkFBa0I7Z0JBQzNDLElBQUksQ0FBQyxlQUFlLEtBQUssdUJBQXVCO2dCQUNoRCxJQUFJLENBQUMsUUFBUSxLQUFLLHFDQUFxQztnQkFDdkQsSUFBSSxDQUFDLFFBQVEsS0FBSyxrQkFBa0I7Z0JBQ3BDLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFBO1lBRS9ELElBQUksZ0JBQWdCO2dCQUFFLFNBQVE7WUFFOUIscUNBQXFDO1lBQ3JDLHVFQUF1RTtZQUN2RSxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVyxLQUFLLEtBQUs7Z0JBQzVDLENBQUMsSUFBSSxDQUFDLGVBQWUsS0FBSyxRQUFRLElBQUksSUFBSSxDQUFDLFdBQVcsS0FBSyxJQUFJLENBQUMsQ0FBQTtZQUVsRSxJQUFJLFdBQVcsRUFBRTtnQkFDZixjQUFjLEVBQUUsQ0FBQTtnQkFDaEIsTUFBTSxXQUFXLEdBQ2YsSUFBSSxDQUFDLGdCQUFnQixLQUFLLENBQUM7b0JBQzNCLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQztvQkFDakIsSUFBSSxDQUFDLG9CQUFvQixJQUFJLEdBQUc7b0JBQ2hDLElBQUksQ0FBQyxRQUFRLElBQUksR0FBRyxDQUFBO2dCQUV0QixJQUFJLFdBQVcsRUFBRTtvQkFDZix1QkFBdUIsRUFBRSxDQUFBO2lCQUMxQjthQUNGO1NBQ0Y7UUFFRCwyQ0FBMkM7UUFDM0MsTUFBTSxvQkFBb0IsR0FBRyxjQUFjLEtBQUssQ0FBQyxJQUFJLHVCQUF1QixJQUFJLGNBQWMsQ0FBQTtRQUU5RixJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQUFDLGtCQUFrQixHQUFHLENBQUMsb0JBQW9CLENBQUE7UUFDckUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQyxxQkFBcUIsR0FBRyxDQUFDLG9CQUFvQixDQUFDLENBQUM7WUFDeEUsZ0ZBQWdGLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQTtRQUV2RixPQUFPLENBQUMsR0FBRyxDQUFDLGNBQWMsWUFBWSxXQUFXLEVBQUU7WUFDakQsY0FBYztZQUNkLHVCQUF1QjtZQUN2QixRQUFRLEVBQUUsQ0FBQyxvQkFBb0I7U0FDaEMsQ0FBQyxDQUFBO0lBQ0osQ0FBQztJQUVEOztPQUVHO0lBQ0ssbUNBQW1DLENBQUMsV0FBbUIsRUFBRSxRQUFpQjtRQUNoRixLQUFLLE1BQU0sR0FBRyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQzNDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUE7WUFFOUIsK0JBQStCO1lBQy9CLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxXQUFXLEVBQUU7Z0JBQy9CLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsdUJBQXVCLEdBQUcsUUFBUSxDQUFBO2dCQUVwRCw2REFBNkQ7Z0JBQzdELElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtvQkFDakIsSUFBSSxDQUFDLGdDQUFnQyxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBQTtpQkFDckQ7YUFDRjtTQUNGO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0ssZ0NBQWdDLENBQUMsUUFBZ0IsRUFBRSxRQUFpQjtRQUMxRSxLQUFLLE1BQU0sR0FBRyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQzNDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUE7WUFFOUIsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLFFBQVEsRUFBRTtnQkFDNUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyx1QkFBdUIsR0FBRyxRQUFRLENBQUE7Z0JBRXBELDZCQUE2QjtnQkFDN0IsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO29CQUNqQixJQUFJLENBQUMsZ0NBQWdDLENBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxDQUFBO2lCQUNyRDthQUNGO1NBQ0Y7SUFDSCxDQUFDO0lBRUQsMkJBQTJCLENBQUMsSUFBd0I7UUFDbEQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxFQUFFO1lBQ3JELE9BQU8sR0FBRyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxJQUFJLENBQUMsQ0FBQyxDQUFBO1FBQzFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQTtRQUNMLE1BQU0sY0FBYyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLG9CQUFvQixLQUFLLEdBQUcsQ0FBQyxDQUFBO1FBQy9HLE1BQU0sVUFBVSxHQUFHLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUNsRSxJQUFJLENBQUMsc0JBQXNCLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxNQUFNLEdBQUcsVUFBVSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQTtRQUM3RixJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDckUsT0FBTyxJQUFJLENBQUE7SUFDYixDQUFDO0lBRUQscUJBQXFCLENBQUMsR0FBdUM7UUFDM0QsR0FBRyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFBO1FBRXhDLElBQUksR0FBRyxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUU7WUFDeEIsTUFBTSxNQUFNLEdBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQ2hDLEdBQUcsY0FBYyxDQUFDLGlCQUFpQixJQUFJLEdBQUcsQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLEVBQUUsR0FBRyxDQUNuRSxDQUFBO1lBQ0QsMkNBQTJDO1lBQzNDLGlJQUFpSTtZQUNqSSxTQUFTO1lBQ1QsT0FBTyxNQUFNLENBQUE7U0FDZDtRQUNELE9BQU8sRUFBRSxFQUFFLENBQUE7SUFFYixDQUFDO0lBRUQsb0JBQW9CLENBQUMsTUFBVztRQUM5QixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUNsQixjQUFjLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUNyQyxDQUFBO0lBQ0gsQ0FBQztJQUNELGFBQWE7UUFDWCxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUNsQixjQUFjLENBQUMsV0FBVyxDQUFDLENBQUE7SUFDL0IsQ0FBQztJQUVELFdBQVcsQ0FBQyxNQUFjO1FBQ3hCLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFBO0lBQzVELENBQUM7SUFFRCxVQUFVLENBQUMsUUFBYTtRQUN0QixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFNLGNBQWMsQ0FBQyxXQUFXLEVBQUUsUUFBUSxDQUFDLENBQUE7SUFDbEUsQ0FBQztJQUVELGlCQUFpQixDQUFDLE1BQWM7UUFDOUIsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQTtJQUNuRSxDQUFDO0lBRUQsZ0JBQWdCLENBQUMsUUFBYTtRQUM1QixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFNLGNBQWMsQ0FBQyxrQkFBa0IsRUFBRSxRQUFRLENBQUMsQ0FBQTtJQUN6RSxDQUFDO0lBRUQsbUJBQW1CLENBQUMsTUFBYyxFQUFFLFNBQWlCO1FBQ25ELE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQU0sY0FBYyxDQUFDLHNCQUFzQixDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFBO0lBQ3JGLENBQUM7SUFFRCxZQUFZLENBQUMsT0FBWTtRQUN2QixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFNLEdBQUcsY0FBYyxDQUFDLGFBQWEsRUFBRSxFQUFFLE9BQU8sQ0FBQyxDQUFBO0lBQ3hFLENBQUM7SUFDRCxtQkFBbUIsQ0FBQyxPQUFZO1FBQzlCLElBQUksT0FBTyxJQUFJLE9BQU8sQ0FBQyxRQUFRLEVBQUU7WUFDL0IsT0FBTyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFRLEVBQUUsRUFBRTtnQkFDcEMsSUFBSSxHQUFHLENBQUMsZUFBZSxLQUFLLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUU7b0JBQzdELElBQUksbUJBQW1CLEdBQUcsQ0FBQyxDQUFBO29CQUMzQixJQUFJLG9CQUFvQixHQUFHLENBQUMsQ0FBQTtvQkFDNUIsR0FBRyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxRQUFhLEVBQUUsRUFBRTt3QkFDckMsSUFBSSxRQUFRLENBQUMsZUFBZSxLQUFLLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxlQUFlLEVBQUU7NEJBQzNFLG1CQUFtQixHQUFHLG1CQUFtQixHQUFHLENBQUMsQ0FBQTt5QkFDOUM7NkJBQU07NEJBQ0wsb0JBQW9CLEdBQUcsb0JBQW9CLEdBQUcsQ0FBQyxDQUFBO3lCQUNoRDtvQkFDSCxDQUFDLENBQUMsQ0FBQTtvQkFDRixHQUFHLENBQUMscUJBQXFCLENBQUMsR0FBRyxtQkFBbUIsQ0FBQTtvQkFDaEQsR0FBRyxDQUFDLHNCQUFzQixDQUFDLEdBQUcsb0JBQW9CLENBQUE7aUJBQ25EO3FCQUFNO29CQUNMLElBQUksR0FBRyxDQUFDLGVBQWUsS0FBSyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxFQUFFO3dCQUM3RCxJQUFJLENBQUMsbUJBQW1CLENBQUMsR0FBRyxDQUFDLENBQUE7cUJBQzlCO2lCQUNGO1lBQ0gsQ0FBQyxDQUFDLENBQUE7U0FDSDtJQUNILENBQUM7SUFDRCxLQUFLLENBQUMsb0JBQW9CLENBQUMsV0FBZ0I7UUFDekMsSUFBSSxXQUFXLElBQUksV0FBVyxDQUFDLFFBQVEsRUFBRTtZQUN2QyxLQUFLLE1BQU0sR0FBRyxJQUFJLFdBQVcsQ0FBQyxRQUFRLEVBQUU7Z0JBQ3RDLElBQUksR0FBRyxDQUFDLGVBQWUsS0FBSyxTQUFTLENBQUMsZUFBZSxDQUFDLE1BQU0sRUFBRTtvQkFDNUQsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMsU0FBUyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxNQUFXLEVBQUUsRUFBRTt3QkFDdkYsSUFBSSxNQUFNLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTzsrQkFDckMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsUUFBUSxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUU7NEJBQzVFLEdBQUcsQ0FBQyxVQUFVLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUE7eUJBQ2pEO29CQUNILENBQUMsQ0FBQyxDQUFBO2lCQUNIO2FBQ0Y7U0FDRjtJQUNILENBQUM7SUFFRCxvQkFBb0IsQ0FBQyxJQUFTO1FBQzVCLCtCQUErQjtRQUMvQixJQUFJLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFRCx5QkFBeUIsQ0FBQyxVQUFlO1FBQ3ZDLElBQUksQ0FBQyxvQ0FBb0MsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUE7SUFDNUQsQ0FBQztJQUlELG9CQUFvQixDQUFDLFVBQWU7UUFDbEMsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBTSxHQUFHLGNBQWMsQ0FBQyxvQkFBb0IsZ0JBQWdCLFVBQVUsRUFBRSxDQUFDLENBQUE7SUFDL0YsQ0FBQztJQUVELCtCQUErQixDQUFDLEdBQVE7UUFDdEMsT0FBTyxJQUFJLENBQUMsSUFBSTthQUNiLElBQUksQ0FBQyxHQUFHLGNBQWMsQ0FBQyx5QkFBeUIsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFBO0lBQzdELENBQUM7SUFFRCxlQUFlLENBQUMsV0FBZ0I7UUFDOUIsT0FBTyxJQUFJLENBQUMsSUFBSTthQUNiLElBQUksQ0FDSCxHQUFHLGNBQWMsQ0FBQyxlQUFlLEVBQUUsRUFDbkMsV0FBVyxDQUNaO2FBQ0EsSUFBSSxDQUNILEdBQUcsQ0FBQyxDQUFDLElBQVMsRUFBRSxFQUFFO1lBQ2hCLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUE7UUFDL0IsQ0FBQyxDQUFDLENBQ0gsQ0FBQTtJQUNMLENBQUM7SUFHRCxzQkFBc0IsQ0FBQyxTQUFpQixFQUFFLE9BQWUsRUFBRSxZQUFvQixFQUFFLElBQVU7UUFDekYsTUFBTSxRQUFRLEdBQUcsSUFBSSxRQUFRLEVBQUUsQ0FBQztRQUNoQyxRQUFRLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQ3hDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxjQUFjLENBQUMsaUJBQWlCLElBQUksU0FBUyxJQUFJLE9BQU8sSUFBSSxZQUFZLEVBQUUsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUNqSCxDQUFDO0lBR0QsYUFBYSxDQUFDLEVBQVU7UUFDdEIsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FDbEIsR0FBRyxjQUFjLENBQUMsYUFBYSxRQUFRLEVBQUUsWUFBWSxDQUN0RCxDQUFDLElBQUksQ0FDSixHQUFHLENBQUMsQ0FBQyxJQUFTLEVBQUUsRUFBRTtZQUNoQixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFBO1FBQzVCLENBQUMsQ0FBQyxDQUNILENBQUE7SUFDSCxDQUFDO0lBRUQsTUFBTSxDQUNKLElBQWMsRUFDZCxXQUFnQixFQUNoQixPQUFhO1FBR2IsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQVMsQ0FBQTtRQUN4QyxJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFBO1FBQ3hCLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQzFDLFFBQVEsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLENBQUE7U0FDM0M7UUFDRCxNQUFNLFdBQVcsR0FBRyxJQUFJLFFBQVEsRUFBRSxDQUFBO1FBQ2xDLFdBQVcsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQTtRQUMxQyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUNuQixHQUFHLGNBQWMsQ0FBQyxXQUFXLFVBQVUsV0FBVyxDQUFDLFNBQVMsRUFBRSxFQUM5RCxXQUFXLEVBQ1gsT0FBTyxDQUNSLENBQUE7SUFDSCxDQUFDO0lBRUQsZ0JBQWdCLENBQUMsUUFBZ0I7UUFDL0IsTUFBTSxTQUFTLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQTtRQUN0QyxNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFBO1FBQzFDLElBQUksUUFBUSxLQUFLLENBQUMsQ0FBQyxFQUFFO1lBQ25CLE9BQU8sUUFBUSxHQUFHLFNBQVMsQ0FBQTtTQUM1QjtRQUNELE9BQU8sUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLEdBQUcsU0FBUyxHQUFHLFFBQVEsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUE7SUFDbkYsQ0FBQztJQUVELDBCQUEwQixDQUFDLFdBQWdCLEVBQUUsVUFBa0I7UUFDN0QsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FDcEIsR0FBRyxjQUFjLENBQUMsZUFBZSxJQUFJLFVBQVUsRUFBRSxFQUNqRCxXQUFXLENBQ1osQ0FBQTtJQUNILENBQUM7SUFFRCxpQkFBaUIsQ0FBQyxPQUFZO1FBQzVCLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQTtJQUN2RCxDQUFDO0lBRUQscUJBQXFCLENBQUMsT0FBWTtRQUNoQyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyx1QkFBdUIsRUFBRSxPQUFPLENBQUMsQ0FBQTtJQUN2RSxDQUFDO0lBRUQsZ0JBQWdCLENBQUMsT0FBWTtRQUMzQixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxpQkFBaUIsRUFBRSxPQUFPLENBQUMsQ0FBQTtJQUNsRSxDQUFDO0lBRUQsMEJBQTBCLENBQUMsT0FBWTtRQUNyQyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyw0QkFBNEIsRUFBRSxPQUFPLENBQUMsQ0FBQTtJQUM3RSxDQUFDO0lBRUQsbUJBQW1CLENBQUMsT0FBWTtRQUM5QixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsY0FBYyxDQUFDLGlCQUFpQixFQUFFLEVBQUUsT0FBTyxDQUFDLENBQUE7SUFDdkUsQ0FBQztJQUVELGtCQUFrQixDQUFDLFNBQWlCLEVBQUUsT0FBZSxFQUFFLFlBQW9CLEVBQUUsUUFBZ0I7UUFDM0YsbUVBQW1FO1FBQ25FLE1BQU0sYUFBYSxHQUFHLElBQUksZUFBZSxDQUFDO1lBQ3hDLFNBQVMsRUFBRSxTQUFTLElBQUksRUFBRTtZQUMxQixPQUFPLEVBQUUsT0FBTyxJQUFJLEVBQUU7WUFDdEIsTUFBTSxFQUFFLFlBQVksSUFBSSxFQUFFO1lBQzFCLFFBQVEsRUFBRSxRQUFRLElBQUksRUFBRTtTQUN6QixDQUFDLENBQUM7UUFFSCxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsY0FBYyxDQUFDLGVBQWUsSUFBSSxhQUFhLENBQUMsUUFBUSxFQUFFLEVBQUUsRUFBRTtZQUNwRixZQUFZLEVBQUUsTUFBTTtZQUNwQixPQUFPLEVBQUU7Z0JBQ1AsUUFBUSxFQUFFLHdJQUF3STthQUNuSjtTQUNGLENBQUMsQ0FBQyxJQUFJLENBQ0wsVUFBVSxDQUFDLENBQUMsS0FBVSxFQUFFLEVBQUU7WUFDeEIsT0FBTyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDakMsQ0FBQyxDQUFDLENBQ0gsQ0FBQztJQUNKLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCw0QkFBNEIsQ0FBQyxNQUFjLEVBQUUsUUFBZ0IsRUFBRSxPQUFlLEVBQUUsV0FBbUI7UUFDakcsTUFBTSxNQUFNLEdBQUcsa0RBQWtELENBQUE7UUFDakUsTUFBTSxPQUFPLEdBQUc7WUFDZCxPQUFPLEVBQUU7Z0JBQ1AsTUFBTTtnQkFDTixRQUFRO2dCQUNSLE9BQU87Z0JBQ1AsV0FBVzthQUNaO1NBQ0YsQ0FBQTtRQUNELE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFBO0lBQ3hDLENBQUM7K0dBanZEVSxhQUFhO21IQUFiLGFBQWEsY0FGWixNQUFNOzs0RkFFUCxhQUFhO2tCQUh6QixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJ1xyXG5pbXBvcnQgeyBEYXRhIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJ1xyXG5pbXBvcnQgeyBTdWJqZWN0LCBPYnNlcnZhYmxlLCBFTVBUWSwgU3Vic2NyaXB0aW9uLCBCZWhhdmlvclN1YmplY3QsIG9mLCB0aHJvd0Vycm9yIH0gZnJvbSAncnhqcydcclxuaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJ1xyXG5pbXBvcnQgeyBOc0NvbnRlbnQgfSBmcm9tICcuLi9fc2VydmljZXMvd2lkZ2V0LWNvbnRlbnQubW9kZWwnXHJcbmltcG9ydCB7IE5zQ29udGVudENvbnN0YW50cyB9IGZyb20gJy4uL19jb25zdGFudHMvd2lkZ2V0LWNvbnRlbnQuY29uc3RhbnRzJ1xyXG5pbXBvcnQgeyBXaWRnZXRDb250ZW50U2VydmljZSB9IGZyb20gJy4uL19zZXJ2aWNlcy93aWRnZXQtY29udGVudC5zZXJ2aWNlJ1xyXG5pbXBvcnQgeyBOc0FwcFRvYywgTnNDb2hvcnRzIH0gZnJvbSAnLi4vbW9kZWxzL2FwcC10b2MubW9kZWwnXHJcbmltcG9ydCB7IFRGZXRjaFN0YXR1cywgQ29uZmlndXJhdGlvbnNTZXJ2aWNlIH0gZnJvbSAnQHN1bmJpcmQtY2IvdXRpbHMtdjInXHJcbi8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZVxyXG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnXHJcbmltcG9ydCB7IENvbnRlbnRMYW5ndWFnZVNlcnZpY2UgfSBmcm9tICdAc3VuYmlyZC1jYi9jb25zdW1wdGlvbidcclxuaW1wb3J0IHsgbWFwLCBjYXRjaEVycm9yIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnXHJcblxyXG4vLyBUT0RPOiBtb3ZlIHRoaXMgaW4gc29tZSBjb21tb24gcGxhY2VcclxuY29uc3QgUFJPVEVDVEVEX1NMQUdfVjggPSAnL2FwaXMvcHJvdGVjdGVkL3Y4J1xyXG5jb25zdCBQUk9YWV9TTEFHX1Y4ID0gJy9hcGlzL3Byb3hpZXMvdjgnXHJcblxyXG5jb25zdCBBUElfRU5EX1BPSU5UUyA9IHtcclxuICBCQVRDSF9DUkVBVEU6IGAke1BST1hZX1NMQUdfVjh9L2xlYXJuZXIvY291cnNlL3YxL2JhdGNoL2NyZWF0ZWAsXHJcbiAgQ09OVEVOVF9QQVJFTlRTOiBgJHtQUk9URUNURURfU0xBR19WOH0vY29udGVudC9wYXJlbnRzYCxcclxuICBDT05URU5UX05FWFQ6IGAke1BST1RFQ1RFRF9TTEFHX1Y4fS9jb250ZW50L25leHRgLFxyXG4gIENPTlRFTlRfSElTVE9SWVYyOiBgL2FwaXMvcHJveGllcy92OC9yZWFkL2NvbnRlbnQtcHJvZ3Jlc2AsXHJcbiAgQ09OVEVOVF9QQVJFTlQ6IChjb250ZW50SWQ6IHN0cmluZykgPT4gYCR7UFJPVEVDVEVEX1NMQUdfVjh9L2NvbnRlbnQvJHtjb250ZW50SWR9L3BhcmVudGAsXHJcbiAgQ09OVEVOVF9BVVRIX1BBUkVOVDogKGNvbnRlbnRJZDogc3RyaW5nLCByb290T3JnOiBzdHJpbmcsIG9yZzogc3RyaW5nKSA9PlxyXG4gICAgYC9hcGlzL2F1dGhBcGkvYWN0aW9uL2NvbnRlbnQvcGFyZW50L2hpZXJhcmNoeS8ke2NvbnRlbnRJZH0/cm9vdE9yZz0ke3Jvb3RPcmd9Jm9yZz0ke29yZ31gLFxyXG4gIENPSE9SVFM6IChjb2hvcnRUeXBlOiBOc0NvaG9ydHMuRUNvaG9ydFR5cGVzLCBjb250ZW50SWQ6IHN0cmluZykgPT5cclxuICAgIGAke1BST1RFQ1RFRF9TTEFHX1Y4fS9jb2hvcnRzLyR7Y29ob3J0VHlwZX0vJHtjb250ZW50SWR9YCxcclxuICBFWFRFUk5BTF9DT05URU5UOiAoY29udGVudElkOiBzdHJpbmcpID0+XHJcbiAgICBgJHtQUk9URUNURURfU0xBR19WOH0vY29udGVudC9leHRlcm5hbC1hY2Nlc3MvJHtjb250ZW50SWR9YCxcclxuICBDT0hPUlRTX0dST1VQX1VTRVI6IChncm91cElkOiBudW1iZXIpID0+IGAke1BST1RFQ1RFRF9TTEFHX1Y4fS9jb2hvcnRzLyR7Z3JvdXBJZH1gLFxyXG4gIFJFTEFURURfUkVTT1VSQ0U6IChjb250ZW50SWQ6IHN0cmluZywgY29udGVudFR5cGU6IHN0cmluZykgPT5cclxuICAgIGAke1BST1RFQ1RFRF9TTEFHX1Y4fS9raHViL2ZldGNoUmVsYXRlZFJlc291cmNlcy8ke2NvbnRlbnRJZH0vJHtjb250ZW50VHlwZX1gLFxyXG4gIFBPU1RfQVNTRVNTTUVOVDogKGNvbnRlbnRJZDogc3RyaW5nKSA9PlxyXG4gICAgYCR7UFJPVEVDVEVEX1NMQUdfVjh9L3VzZXIvZXZhbHVhdGUvcG9zdC1hc3Nlc3NtZW50LyR7Y29udGVudElkfWAsXHJcbiAgR0VUX0NPTlRFTlQ6IChjb250ZW50SWQ6IHN0cmluZykgPT5cclxuICAgIGAke1BST1hZX1NMQUdfVjh9L2FjdGlvbi9jb250ZW50L3YzL3JlYWQvJHtjb250ZW50SWR9YCxcclxuICBDRVJUX0RPV05MT0FEOiAoY2VydElkOiBhbnkpID0+IGAke1BST1RFQ1RFRF9TTEFHX1Y4fS9jb2hvcnRzL2NvdXJzZS9iYXRjaC9jZXJ0L2Rvd25sb2FkLyR7Y2VydElkfWAsXHJcbiAgU0VSVkVSX0RBVEU6ICdhcGlzL3B1YmxpYy92OC9zeXN0ZW1EYXRlJyxcclxuICBTSEFSRV9DT05URU5UOiAnL2FwaXMvcHJveGllcy92OC91c2VyL3YxL2NvbnRlbnQvcmVjb21tZW5kJyxcclxuICBHRVRfRk9STV9CWUlEOiAoZm9ybUlkOiBzdHJpbmcpID0+IGBhcGlzL3Byb3hpZXMvdjgvZm9ybXMvdjIvZ2V0Rm9ybUJ5SWQ/Zm9ybUlkPSR7Zm9ybUlkfWAsXHJcbiAgLy8gU1VCTUlUX0ZPUk06IGAvYXBpcy9wcm94aWVzL3Y4L2Zvcm1zL3YxL3NhdmVGb3JtU3VibWl0YCxcclxuICBTVUJNSVRfRk9STTogYGFwaXMvcHJveGllcy92OC9mb3Jtcy92Mi9zYXZlRm9ybVN1Ym1pdGAsXHJcbiAgR0VUX0ZPUk1fQllJRF9QVUJMSUM6IChmb3JtSWQ6IHN0cmluZykgPT4gYGFwaXMvcHVibGljL3Y4L3B1YmxpYy9mb3Jtcy92Mi9nZXRGb3JtQnlJZD9mb3JtSWQ9JHtmb3JtSWR9YCxcclxuICBTVUJNSVRfRk9STV9QVUJMSUM6IGBhcGlzL3B1YmxpYy92OC9wdWJsaWMvZm9ybXMvdjIvc2F2ZUZvcm1TdWJtaXRgLFxyXG4gIC8vIGdldCBhbnN3ZXJzIGZvciBmb3JtXHJcbiAgR0VUX0FQUExJQ0FUSU9OU19CWV9JRDogKGZvcm1JZDogc3RyaW5nLCBjb250ZXh0SWQ6IHN0cmluZykgPT4gYC9hcGlzL3Byb3hpZXMvdjgvZm9ybXMvdjIvZ2V0QXBwbGljYXRpb25zQnlJZD9mb3JtSWQ9JHtmb3JtSWR9JmNvbnRleHRJZD0ke2NvbnRleHRJZH1gLFxyXG4gIEFJX1JFU09VUkNFX1ZUVF9GSUxFOiBgJHtQUk9YWV9TTEFHX1Y4fS9jaGF0Ym90L3YzL3RyYW5zY29kZXIvc3RhdHNgLFxyXG4gIC8vIEdFVF9GT1JNX0JZSUQ6IChmb3JtSWQ6IHN0cmluZykgPT4gYGFwaXMvcHJveGllcy92OC9mb3Jtcy9nZXRGb3JtQnlJZD9pZD0ke2Zvcm1JZH1gLFxyXG4gIFBSRV9FTlJPTExNRU5UX1NUQVRFX1JFQUQ6IGAvYXBpcy9wcm94aWVzL3Y4L2NvbnRlbnQvdjIvc3RhdGUvcmVhZGAsXHJcbiAgQ1JFQVRFX1JFU09VUkNFOiBgYXBpcy9wcm94aWVzL3Y4L2FjdGlvbi9jb250ZW50L3YzL2NyZWF0ZWAsXHJcbiAgUkVBRF9SRVNPVVJDRTogYGFwaXMvcHJveGllcy92OC9hY3Rpb24vY29udGVudC92My9gLFxyXG4gIFVQTE9BRF9GSUxFOiBgYXBpcy9wcm94aWVzL3Y4L3VwbG9hZC9hY3Rpb24vY29udGVudC92My9gLFxyXG4gIFVQREFURV9SRVNPVVJDRTogYGFwaXMvcHJveGllcy92OC9hY3Rpb24vY29udGVudC92My91cGRhdGVgLFxyXG4gIFNFQVJDSDogYGFwaXMvcHJveGllcy92OC9hc3NpZ25tZW50L3YxL3NlYXJjaGAsXHJcbiAgU1VCTUlUX0RSQUZUX0FTU0lHTk1FTlQ6IGBhcGlzL3Byb3hpZXMvdjgvYXNzaWdubWVudC92MS9zdWJtaXREcmFmdGAsXHJcbiAgU1VCTUlUX0FTU0lHTk1FTlQ6IGBhcGlzL3Byb3hpZXMvdjgvYXNzaWdubWVudC92MS9zdWJtaXRgLFxyXG4gIEFTU0lHTk1FTlRfU1RBVFVTOiBgYXBpcy9wcm94aWVzL3Y4L2Zvcm1zL3YyL3N1Ym1pc3Npb25zL3NlYXJjaGAsXHJcbiAgVVBMT0FEX0FTU0lHTk1FTlQ6IGBhcGlzL3Byb3hpZXMvdjgvc3RvcmFnZS92MS9icC9hc3NpZ25tZW50L2Fuc3dlcmAsXHJcbiAgUkVBRF9BU1NJR05NRU5UOiBgYXBpcy9wcm94aWVzL3Y4L3N0b3JhZ2UvdjEvYnAvYXNzaWdubWVudC9hbnN3ZXIvcmVhZC9maWxlYCxcclxuICBOT1RJRllfQVNTSUdOTUVOVF9TVUJNSVNTSU9OOiBgYXBpcy9wcm94aWVzL3Y4L3YxL25vdGlmeUFzc2lnbm1lbnQvc3VibWl0YCxcclxufVxyXG5cclxuQEluamVjdGFibGUoe1xyXG4gIHByb3ZpZGVkSW46ICdyb290J1xyXG59KVxyXG5leHBvcnQgY2xhc3MgQXBwVG9jU2VydmljZSB7XHJcbiAgYW5hbHl0aWNzUmVwbGF5U3ViamVjdDogU3ViamVjdDxhbnk+ID0gbmV3IFN1YmplY3QoKVxyXG4gIGFuYWx5dGljc0ZldGNoU3RhdHVzOiBURmV0Y2hTdGF0dXMgPSAnbm9uZSdcclxuICBiYXRjaFJlcGxheVN1YmplY3Q6IFN1YmplY3Q8YW55PiA9IG5ldyBTdWJqZWN0KClcclxuICBzZXRCYXRjaERhdGFTdWJqZWN0OiBTdWJqZWN0PGFueT4gPSBuZXcgU3ViamVjdCgpXHJcbiAgZ2V0U2VsZWN0ZWRCYXRjaDogU3ViamVjdDxhbnk+ID0gbmV3IFN1YmplY3QoKVxyXG4gIHNldFdGRGF0YVN1YmplY3Q6IFN1YmplY3Q8YW55PiA9IG5ldyBTdWJqZWN0KClcclxuICByZXN1bWVEYXRhOiBTdWJqZWN0PE5zQ29udGVudC5JQ29udGludWVMZWFybmluZ0RhdGEgfCBudWxsPiA9IG5ldyBTdWJqZWN0PGFueT4oKVxyXG4gIHByaXZhdGUgc2hvd1N1YnRpdGxlT25CYW5uZXJzID0gZmFsc2VcclxuICBwcml2YXRlIGNhblNob3dEZXNjcmlwdGlvbiA9IGZhbHNlXHJcbiAgcmVzdW1lRGF0YVN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uIHwgbnVsbCA9IG51bGxcclxuICBwcmltYXJ5Q2F0ZWdvcnkgPSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeVxyXG4gIHByaXZhdGUgdXBkYXRlUmV2aWV3cyA9IG5ldyBCZWhhdmlvclN1YmplY3QoZmFsc2UpXHJcbiAgdXBkYXRlUmV2aWV3c09ic2VydmFibGUgPSB0aGlzLnVwZGF0ZVJldmlld3MuYXNPYnNlcnZhYmxlKClcclxuICBwdWJsaWMgc2VydmVyRGF0ZSA9IG5ldyBCZWhhdmlvclN1YmplY3QoJycpXHJcbiAgY3VycmVudFNlcnZlckRhdGUgPSB0aGlzLnNlcnZlckRhdGUuYXNPYnNlcnZhYmxlKClcclxuICBwdWJsaWMgY29udGVudExvYWRlciA9IG5ldyBCZWhhdmlvclN1YmplY3QoZmFsc2UpXHJcbiAgY29udGVudExvYWRlciQgPSB0aGlzLmNvbnRlbnRMb2FkZXIuYXNPYnNlcnZhYmxlKClcclxuICBwdWJsaWMgZ2V0UGFnZVNjcm9sbCA9IG5ldyBCZWhhdmlvclN1YmplY3QodHJ1ZSlcclxuICB1cGRhdGVQYWdlU2Nyb2xsID0gdGhpcy5nZXRQYWdlU2Nyb2xsLmFzT2JzZXJ2YWJsZSgpXHJcbiAgcHVibGljIGhhc2htYXA6IGFueSA9IHt9XHJcbiAgcHVibGljIGhhc2htYXBVcGRhdGVkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxhbnk+KG51bGwpXHJcbiAgaGFzaG1hcFVwZGF0ZWQkID0gdGhpcy5oYXNobWFwVXBkYXRlZC5hc09ic2VydmFibGUoKVxyXG4gIHByaXZhdGUgdHJhbnNyaXB0aW9uRGF0YVN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGFueT4obnVsbCk7IC8vIFN0YXJ0IHdpdGggbnVsbFxyXG4gIHRyYW5zY3JpcHRpb25EYXRhJCA9IHRoaXMudHJhbnNyaXB0aW9uRGF0YVN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XHJcbiAgcHVibGljIHRyYW5zcmlwdGlvbkFjdGl2ZUxhbmd1YWdlRGF0YU9iamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8YW55PihudWxsKTtcclxuICBwdWJsaWMgdHJhbnNyaXB0aW9uQWN0aXZlTGFuZ3VhZ2VEYXRhT2JqZWN0JCA9IHRoaXMudHJhbnNyaXB0aW9uQWN0aXZlTGFuZ3VhZ2VEYXRhT2JqZWN0LmFzT2JzZXJ2YWJsZSgpO1xyXG4gIHB1YmxpYyB0cmFuc3JpcHRpb25JZGVudGlmaWVyID0gbmV3IFN1YmplY3QoKTsgLy8gU3RhcnQgd2l0aCBudWxsXHJcbiAgY2hhbmdlVHJhbnNjcmlwdGlvbkxhbmd1YWdlRXZlbnQgPSBuZXcgU3ViamVjdCgpXHJcbiAgcGxheVRyYW5zY3JpcHRpb25WaWRlbyA9IG5ldyBTdWJqZWN0KClcclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGh0dHA6IEh0dHBDbGllbnQsIHByaXZhdGUgY29udGVudExhbmdTdmM6IENvbnRlbnRMYW5ndWFnZVNlcnZpY2UsIHByaXZhdGUgY29uZmlnU3ZjOiBDb25maWd1cmF0aW9uc1NlcnZpY2UsIHByaXZhdGUgd2lkZ2V0U3ZjOiBXaWRnZXRDb250ZW50U2VydmljZSkge1xyXG4gICAgLy8gdGhpcyByZXN1bWUgZGF0YSBzdWJzY3JpcHRpb24gaXMgZm9yIG9uIGxvYWRcclxuICAgIHRoaXMucmVzdW1lRGF0YVN1YnNjcmlwdGlvbiA9IHRoaXMucmVzdW1lRGF0YS5zdWJzY3JpYmUoXHJcbiAgICAgIChfZGF0YVJlc3VsdDogYW55KSA9PiB7XHJcbiAgICAgIH0pXHJcbiAgfVxyXG5cclxuICBnZXQgc3VidGl0bGVPbkJhbm5lcnMoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5zaG93U3VidGl0bGVPbkJhbm5lcnNcclxuICB9XHJcbiAgc2V0IHN1YnRpdGxlT25CYW5uZXJzKHZhbDogYm9vbGVhbikge1xyXG4gICAgdGhpcy5zaG93U3VidGl0bGVPbkJhbm5lcnMgPSB2YWxcclxuICB9XHJcbiAgZ2V0IHNob3dEZXNjcmlwdGlvbigpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLmNhblNob3dEZXNjcmlwdGlvblxyXG4gIH1cclxuICBzZXQgc2hvd0Rlc2NyaXB0aW9uKHZhbDogYm9vbGVhbikge1xyXG4gICAgdGhpcy5jYW5TaG93RGVzY3JpcHRpb24gPSB2YWxcclxuICB9XHJcblxyXG4gIHVwZGF0ZUJhdGNoRGF0YSgpIHtcclxuICAgIHRoaXMuYmF0Y2hSZXBsYXlTdWJqZWN0Lm5leHQoKVxyXG4gIH1cclxuXHJcbiAgc2V0QmF0Y2hEYXRhKGRhdGE6IE5zQ29udGVudC5JQmF0Y2hMaXN0UmVzcG9uc2UpIHtcclxuICAgIHRoaXMuc2V0QmF0Y2hEYXRhU3ViamVjdC5uZXh0KGRhdGEpXHJcbiAgfVxyXG5cclxuICBzZXRXRkRhdGEoZGF0YTogYW55KSB7XHJcbiAgICB0aGlzLnNldFdGRGF0YVN1YmplY3QubmV4dChkYXRhKVxyXG4gIH1cclxuXHJcbiAgdXBkYXRlUmVzdW1hRGF0YShkYXRhOiBhbnkpIHtcclxuICAgIHRoaXMucmVzdW1lRGF0YS5uZXh0KGRhdGEpXHJcbiAgfVxyXG5cclxuICBjaGFuZ2VVcGRhdGVSZXZpZXdzKHN0YXRlOiBib29sZWFuKSB7XHJcbiAgICB0aGlzLnVwZGF0ZVJldmlld3MubmV4dChzdGF0ZSlcclxuICB9XHJcbiAgZ2V0U2VsZWN0ZWRCYXRjaERhdGEoZGF0YTogYW55KSB7XHJcbiAgICB0aGlzLmdldFNlbGVjdGVkQmF0Y2gubmV4dChkYXRhKVxyXG4gIH1cclxuXHJcbiAgY2hhbmdlU2VydmVyRGF0ZShzdGF0ZTogYW55KSB7XHJcbiAgICB0aGlzLnNlcnZlckRhdGUubmV4dChzdGF0ZSlcclxuICB9XHJcblxyXG4gIG1hcFNlc3Npb25Db21wbGV0aW9uUGVyY2VudGFnZShiYXRjaERhdGE6IGFueSwgcmVzdW1lRGF0YVBhc3M/OiBhbnkpIHtcclxuICAgIGlmIChyZXN1bWVEYXRhUGFzcyAmJiByZXN1bWVEYXRhUGFzcy5sZW5ndGgpIHtcclxuICAgICAgaWYgKHJlc3VtZURhdGFQYXNzICYmIHJlc3VtZURhdGFQYXNzLmxlbmd0aCAmJiBiYXRjaERhdGEuY29udGVudCAmJiBiYXRjaERhdGEuY29udGVudC5sZW5ndGgpIHtcclxuICAgICAgICB0aGlzLnNlc3Npb25Db21wbGV0aW9uUGVyY2VudGFnZShiYXRjaERhdGEsIHJlc3VtZURhdGFQYXNzKVxyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLnJlc3VtZURhdGFTdWJzY3JpcHRpb24gPSB0aGlzLnJlc3VtZURhdGEuc3Vic2NyaWJlKFxyXG4gICAgICAgIChkYXRhUmVzdWx0OiBhbnkpID0+IHtcclxuICAgICAgICAgIGlmIChkYXRhUmVzdWx0ICYmIGRhdGFSZXN1bHQubGVuZ3RoICYmIGJhdGNoRGF0YS5jb250ZW50ICYmIGJhdGNoRGF0YS5jb250ZW50Lmxlbmd0aCkge1xyXG4gICAgICAgICAgICB0aGlzLnNlc3Npb25Db21wbGV0aW9uUGVyY2VudGFnZShiYXRjaERhdGEsIGRhdGFSZXN1bHQpXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgICAgICAoKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLmNvbnRlbnRMb2FkZXIubmV4dChmYWxzZSlcclxuICAgICAgICB9KVxyXG4gICAgfVxyXG5cclxuICB9XHJcbiAgc2Vzc2lvbkNvbXBsZXRpb25QZXJjZW50YWdlKGJhdGNoRGF0YTogYW55LCByZXN1bWVEYXRhUGFzczogYW55KSB7XHJcbiAgICBpZiAocmVzdW1lRGF0YVBhc3MgJiYgcmVzdW1lRGF0YVBhc3MubGVuZ3RoKSB7XHJcbiAgICAgIGlmIChiYXRjaERhdGEgJiYgYmF0Y2hEYXRhLmNvbnRlbnRbMF0gJiZcclxuICAgICAgICBiYXRjaERhdGEuY29udGVudFswXS5iYXRjaEF0dHJpYnV0ZXMgJiZcclxuICAgICAgICBiYXRjaERhdGEuY29udGVudFswXS5iYXRjaEF0dHJpYnV0ZXMuc2Vzc2lvbkRldGFpbHNfdjJcclxuICAgICAgKSB7XHJcbiAgICAgICAgYmF0Y2hEYXRhLmNvbnRlbnRbMF0uYmF0Y2hBdHRyaWJ1dGVzLnNlc3Npb25EZXRhaWxzX3YyLm1hcCgoc2Q6IGFueSkgPT4ge1xyXG4gICAgICAgICAgY29uc3QgZm91bmRDb250ZW50ID0gcmVzdW1lRGF0YVBhc3MuZmluZCgoZWw6IGFueSkgPT4gZWwuY29udGVudElkID09PSBzZC5zZXNzaW9uSWQpXHJcbiAgICAgICAgICBpZiAoZm91bmRDb250ZW50KSB7XHJcbiAgICAgICAgICAgIHNkLmNvbXBsZXRpb25QZXJjZW50YWdlID0gZm91bmRDb250ZW50LmNvbXBsZXRpb25QZXJjZW50YWdlXHJcbiAgICAgICAgICAgIHNkLmNvbXBsZXRpb25TdGF0dXMgPSBmb3VuZENvbnRlbnQuc3RhdHVzXHJcbiAgICAgICAgICAgIHNkLmxhc3RDb21wbGV0ZWRUaW1lID0gZm91bmRDb250ZW50Lmxhc3RDb21wbGV0ZWRUaW1lXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSlcclxuICAgICAgICB0aGlzLmNvbnRlbnRMb2FkZXIubmV4dChmYWxzZSlcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgc2hvd1N0YXJ0QnV0dG9uKGNvbnRlbnQ6IE5zQ29udGVudC5JQ29udGVudCB8IG51bGwpOiB7IHNob3c6IGJvb2xlYW47IG1zZzogc3RyaW5nIH0ge1xyXG4gICAgY29uc3Qgc3RhdHVzID0ge1xyXG4gICAgICBzaG93OiBmYWxzZSxcclxuICAgICAgbXNnOiAnJyxcclxuICAgIH1cclxuICAgIGlmIChjb250ZW50KSB7XHJcbiAgICAgIGlmIChcclxuICAgICAgICBjb250ZW50LmFydGlmYWN0VXJsICYmIGNvbnRlbnQuYXJ0aWZhY3RVcmwubWF0Y2goL3lvdXR1KC4pP2JlL2dpKSAmJlxyXG4gICAgICAgIHRoaXMuY29uZmlnU3ZjLnVzZXJQcm9maWxlICYmXHJcbiAgICAgICAgdGhpcy5jb25maWdTdmMudXNlclByb2ZpbGUuY291bnRyeSA9PT0gJ0NoaW5hJ1xyXG4gICAgICApIHtcclxuICAgICAgICBzdGF0dXMuc2hvdyA9IGZhbHNlXHJcbiAgICAgICAgc3RhdHVzLm1zZyA9ICd5b3V0dWJlRm9yYmlkZGVuJ1xyXG4gICAgICAgIHJldHVybiBzdGF0dXNcclxuICAgICAgfVxyXG4gICAgICBpZiAoY29udGVudC5yZXNvdXJjZVR5cGUgIT09ICdDZXJ0aWZpY2F0aW9uJykge1xyXG4gICAgICAgIHN0YXR1cy5zaG93ID0gdHJ1ZVxyXG4gICAgICAgIHJldHVybiBzdGF0dXNcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHN0YXR1c1xyXG4gIH1cclxuXHJcbiAgaW5pdERhdGEoZGF0YTogRGF0YSwgbmVlZFJlc3VtZURhdGE6IGJvb2xlYW4gPSBmYWxzZSk6IE5zQXBwVG9jLklXc1RvY1Jlc3BvbnNlIHtcclxuICAgIGxldCBjb250ZW50OiBOc0NvbnRlbnQuSUNvbnRlbnQgfCBudWxsID0gbnVsbFxyXG4gICAgbGV0IGVycm9yQ29kZTogTnNBcHBUb2MuRVdzVG9jRXJyb3JDb2RlIHwgbnVsbCA9IG51bGxcclxuICAgIHRoaXMuY29udGVudExvYWRlci5uZXh0KHRydWUpXHJcbiAgICBpZiAoZGF0YS5jb250ZW50ICYmIGRhdGEuY29udGVudC5kYXRhICYmIGRhdGEuY29udGVudC5kYXRhLmlkZW50aWZpZXIpIHtcclxuICAgICAgY29udGVudCA9IGRhdGEuY29udGVudC5kYXRhXHJcbiAgICAgIGlmIChuZWVkUmVzdW1lRGF0YSkge1xyXG4gICAgICAgIHRoaXMucmVzdW1lRGF0YVN1YnNjcmlwdGlvbiA9IHRoaXMucmVzdW1lRGF0YS5zdWJzY3JpYmUoXHJcbiAgICAgICAgICAoZGF0YVJlc3VsdDogYW55KSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChkYXRhUmVzdWx0ICYmIGRhdGFSZXN1bHQubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5jb250ZW50TG9hZGVyLm5leHQodHJ1ZSlcclxuICAgICAgICAgICAgICB0aGlzLm1hcENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQsIGRhdGFSZXN1bHQpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICAoKSA9PiB7XHJcbiAgICAgICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogbm8tY29uc29sZVxyXG4gICAgICAgICAgICBjb25zb2xlLmxvZygnZXJyb3Igb24gcmVzdW1lRGF0YVN1YnNjcmlwdGlvbicpXHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgIClcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLmNvbnRlbnRMb2FkZXIubmV4dChmYWxzZSlcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5jb250ZW50TG9hZGVyLm5leHQoZmFsc2UpXHJcbiAgICAgIGlmIChkYXRhLmVycm9yKSB7XHJcbiAgICAgICAgZXJyb3JDb2RlID0gTnNBcHBUb2MuRVdzVG9jRXJyb3JDb2RlLkFQSV9GQUlMVVJFXHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgZXJyb3JDb2RlID0gTnNBcHBUb2MuRVdzVG9jRXJyb3JDb2RlLk5PX0RBVEFcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgLy8gdGhpcy5jb250ZW50TG9hZGVyLm5leHQoZmFsc2UpXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBjb250ZW50LFxyXG4gICAgICBlcnJvckNvZGUsXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBtYXBDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50OiBOc0NvbnRlbnQuSUNvbnRlbnQgfCBudWxsLCBkYXRhUmVzdWx0OiBhbnkpIHtcclxuICAgIGlmIChjb250ZW50ICYmIGNvbnRlbnQuY2hpbGRyZW4pIHtcclxuICAgICAgY29udGVudC5jaGlsZHJlbi5tYXAoY2hpbGQgPT4ge1xyXG4gICAgICAgIGNvbnN0IGZvdW5kQ29udGVudCA9IGRhdGFSZXN1bHQuZmluZCgoZWw6IGFueSkgPT4gZWwuY29udGVudElkID09PSBjaGlsZC5pZGVudGlmaWVyKVxyXG4gICAgICAgIGlmIChmb3VuZENvbnRlbnQpIHtcclxuICAgICAgICAgIGNoaWxkLmNvbXBsZXRpb25QZXJjZW50YWdlID0gZm91bmRDb250ZW50LmNvbXBsZXRpb25QZXJjZW50YWdlIHx8IGZvdW5kQ29udGVudC5wcm9ncmVzc1xyXG4gICAgICAgICAgY2hpbGQuY29tcGxldGlvblN0YXR1cyA9IGZvdW5kQ29udGVudC5zdGF0dXNcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdGhpcy5tYXBDb21wbGV0aW9uUGVyY2VudGFnZShjaGlsZCwgZGF0YVJlc3VsdClcclxuICAgICAgICB9XHJcbiAgICAgIH0pXHJcbiAgICAgIHRoaXMuY29udGVudExvYWRlci5uZXh0KGZhbHNlKVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5jb250ZW50TG9hZGVyLm5leHQoZmFsc2UpXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBtYXBNb2R1bGVDb3VudChjb250ZW50OiBOc0NvbnRlbnQuSUNvbnRlbnQpIHtcclxuICAgIGlmIChjb250ZW50ICYmIGNvbnRlbnQuY2hpbGRyZW4pIHtcclxuICAgICAgY29udGVudC5jaGlsZHJlbi5tYXAoY2hpbGQgPT4ge1xyXG4gICAgICAgIGlmIChjaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk1PRFVMRSkge1xyXG4gICAgICAgICAgY29udGVudFsnbW9kdWxlQ291bnQnXSA9IGNvbnRlbnRbJ21vZHVsZUNvdW50J10gPyBjb250ZW50Wydtb2R1bGVDb3VudCddICsgMSA6IDFcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGNoaWxkLnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuQ09VUlNFKSB7XHJcbiAgICAgICAgICB0aGlzLm1hcE1vZHVsZUNvdW50KGNoaWxkKVxyXG4gICAgICAgIH1cclxuICAgICAgfSlcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldE1pbWVUeXBlKGNvbnRlbnQ6IE5zQ29udGVudC5JQ29udGVudCwgaWRlbnRpZmllcjogc3RyaW5nKTogTnNDb250ZW50LkVNaW1lVHlwZXMge1xyXG4gICAgaWYgKGNvbnRlbnQuaWRlbnRpZmllciA9PT0gaWRlbnRpZmllcikge1xyXG4gICAgICByZXR1cm4gY29udGVudC5taW1lVHlwZVxyXG4gICAgfVxyXG4gICAgaWYgKGNvbnRlbnQgJiYgY29udGVudC5jaGlsZHJlbikge1xyXG4gICAgICBpZiAoY29udGVudC5jaGlsZHJlbi5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAvLyBpZiAoY29udGVudC5jaGlsZHJlblswXS5pZGVudGlmaWVyID09PSBpZGVudGlmaWVyKSB7XHJcbiAgICAgICAgLy8gICByZXR1cm4gY29udGVudC5taW1lVHlwZVxyXG4gICAgICAgIC8vIH1cclxuICAgICAgICAvLyBiaWcgYmx1bmRlciBpbiBkYXRhXHJcbiAgICAgICAgLy8gdGhpcy5sb2dnZXIubG9nKGNvbnRlbnQuaWRlbnRpZmllciwgJ1dyb25nIG1pbWV0eXBlcyBmb3IgcmVzdW1lJylcclxuICAgICAgICByZXR1cm4gY29udGVudC5taW1lVHlwZVxyXG4gICAgICB9XHJcbiAgICAgIGNvbnN0IGZsYXRMaXN0OiBhbnlbXSA9IFtdXHJcbiAgICAgIGNvbnN0IGdldEFsbEl0ZW1zUGVyQ2hpbGRyZW46IGFueSA9IChpdGVtOiBOc0NvbnRlbnQuSUNvbnRlbnQpID0+IHtcclxuICAgICAgICBmbGF0TGlzdC5wdXNoKGl0ZW0pXHJcbiAgICAgICAgaWYgKGl0ZW0uY2hpbGRyZW4pIHtcclxuICAgICAgICAgIHJldHVybiBpdGVtLmNoaWxkcmVuLm1hcCgoaTogTnNDb250ZW50LklDb250ZW50KSA9PiBnZXRBbGxJdGVtc1BlckNoaWxkcmVuKGkpKVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm5cclxuICAgICAgfVxyXG4gICAgICBnZXRBbGxJdGVtc1BlckNoaWxkcmVuKGNvbnRlbnQpXHJcbiAgICAgIGNvbnN0IGNobGQgPSBfLmZpcnN0KF8uZmlsdGVyKGZsYXRMaXN0LCB7IGlkZW50aWZpZXIgfSkpXHJcbiAgICAgIHJldHVybiAoY2hsZCAmJiBjaGxkLm1pbWVUeXBlKSB8fCAnJ1xyXG4gICAgfVxyXG4gICAgLy8gcmV0dXJuIGNobGQubWltZVR5cGVcclxuICAgIHJldHVybiBOc0NvbnRlbnQuRU1pbWVUeXBlcy5VTktOT1dOXHJcbiAgfVxyXG5cclxuICBnZXRUb2NTdHJ1Y3R1cmUoXHJcbiAgICBjb250ZW50OiBOc0NvbnRlbnQuSUNvbnRlbnQsXHJcbiAgICB0b2NTdHJ1Y3R1cmU6IE5zQXBwVG9jLklUb2NTdHJ1Y3R1cmUsXHJcbiAgKTogTnNBcHBUb2MuSVRvY1N0cnVjdHVyZSB7XHJcbiAgICBpZiAoXHJcbiAgICAgIGNvbnRlbnQgJiZcclxuICAgICAgIShjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gdGhpcy5wcmltYXJ5Q2F0ZWdvcnkuUkVTT1VSQ0VcclxuICAgICAgICAvLyB8fCBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gdGhpcy5wcmltYXJ5Q2F0ZWdvcnkuS05PV0xFREdFX0FSVElGQUNUKVxyXG4gICAgICAgIHx8IGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSB0aGlzLnByaW1hcnlDYXRlZ29yeS5QUkFDVElDRV9SRVNPVVJDRVxyXG4gICAgICAgIHx8IGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSB0aGlzLnByaW1hcnlDYXRlZ29yeS5GSU5BTF9BU1NFU1NNRU5UXHJcbiAgICAgICAgfHwgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHRoaXMucHJpbWFyeUNhdGVnb3J5Lk9GRkxJTkVfU0VTU0lPTlxyXG4gICAgICApKSB7XHJcbiAgICAgIGlmIChjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuQ09VUlNFKSB7XHJcbiAgICAgICAgdG9jU3RydWN0dXJlLmNvdXJzZSArPSAxXHJcbiAgICAgIH0gZWxzZSBpZiAoY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk1PRFVMRSkge1xyXG4gICAgICAgIHRvY1N0cnVjdHVyZS5sZWFybmluZ01vZHVsZSArPSAxXHJcbiAgICAgIH1cclxuICAgICAgXy5lYWNoKGNvbnRlbnQuY2hpbGRyZW4sIGNoaWxkID0+IHtcclxuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6IG5vLXBhcmFtZXRlci1yZWFzc2lnbm1lbnRcclxuICAgICAgICB0b2NTdHJ1Y3R1cmUgPSB0aGlzLmdldFRvY1N0cnVjdHVyZShjaGlsZCwgdG9jU3RydWN0dXJlKVxyXG4gICAgICB9KVxyXG4gICAgfSBlbHNlIGlmIChcclxuICAgICAgY29udGVudCAmJlxyXG4gICAgICAoXHJcbiAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LlJFU09VUkNFXHJcbiAgICAgICAgLy8gfHwgY29udGVudC5jb250ZW50VHlwZSA9PT0gJ0tub3dsZWRnZSBBcnRpZmFjdCdcclxuICAgICAgICB8fCBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuUFJBQ1RJQ0VfUkVTT1VSQ0VcclxuICAgICAgICB8fCBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVFxyXG4gICAgICAgIHx8IGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5PRkZMSU5FX1NFU1NJT04pXHJcbiAgICApIHtcclxuICAgICAgc3dpdGNoIChjb250ZW50Lm1pbWVUeXBlKSB7XHJcbiAgICAgICAgLy8gY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5IQU5EU19PTjpcclxuICAgICAgICAvLyAgIHRvY1N0cnVjdHVyZS5oYW5kc09uICs9IDFcclxuICAgICAgICAvLyAgIGJyZWFrXHJcbiAgICAgICAgY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5NUDM6XHJcbiAgICAgICAgICB0b2NTdHJ1Y3R1cmUucG9kY2FzdCArPSAxXHJcbiAgICAgICAgICBicmVha1xyXG4gICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuTVA0OlxyXG4gICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuTTNVODpcclxuICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLllPVVRVQkU6XHJcbiAgICAgICAgICB0b2NTdHJ1Y3R1cmUudmlkZW8gKz0gMVxyXG4gICAgICAgICAgYnJlYWtcclxuICAgICAgICAvLyBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLklOVEVSQUNUSU9OOlxyXG4gICAgICAgIC8vICAgdG9jU3RydWN0dXJlLmludGVyYWN0aXZlVmlkZW8gKz0gMVxyXG4gICAgICAgIC8vICAgYnJlYWtcclxuICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLlBERjpcclxuICAgICAgICAgIHRvY1N0cnVjdHVyZS5wZGYgKz0gMVxyXG4gICAgICAgICAgYnJlYWtcclxuICAgICAgICAvLyBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLkhUTUw6XHJcbiAgICAgICAgY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5URVhUX1dFQjpcclxuICAgICAgICAgIHRvY1N0cnVjdHVyZS53ZWJQYWdlICs9IDFcclxuICAgICAgICAgIGJyZWFrXHJcbiAgICAgICAgY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5TVVJWRVk6XHJcbiAgICAgICAgICB0b2NTdHJ1Y3R1cmUuc3VydmV5ICs9IDFcclxuICAgICAgICAgIGJyZWFrXHJcbiAgICAgICAgY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5RVUlaOlxyXG4gICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuQVBQTElDQVRJT05fSlNPTjpcclxuICAgICAgICAgIC8vIGlmIChjb250ZW50LnJlc291cmNlVHlwZSA9PT0gJ0Fzc2Vzc21lbnQnKSB7XHJcbiAgICAgICAgICB0b2NTdHJ1Y3R1cmUuYXNzZXNzbWVudCArPSAxXHJcbiAgICAgICAgICAvLyB9IGVsc2Uge1xyXG4gICAgICAgICAgLy8gICB0b2NTdHJ1Y3R1cmUucXVpeiArPSAxXHJcbiAgICAgICAgICAvLyB9XHJcbiAgICAgICAgICBicmVha1xyXG4gICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuT0ZGTElORV9TRVNTSU9OOlxyXG4gICAgICAgICAgLy8gaWYgKGNvbnRlbnQucmVzb3VyY2VUeXBlID09PSAnQXNzZXNzbWVudCcpIHtcclxuICAgICAgICAgIHRvY1N0cnVjdHVyZS5vZmZsaW5lU2Vzc2lvbiArPSAxXHJcbiAgICAgICAgICAvLyB9IGVsc2Uge1xyXG4gICAgICAgICAgLy8gICB0b2NTdHJ1Y3R1cmUucXVpeiArPSAxXHJcbiAgICAgICAgICAvLyB9XHJcbiAgICAgICAgICBicmVha1xyXG4gICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuUFJBQ1RJQ0VfUkVTT1VSQ0U6XHJcbiAgICAgICAgICBpZiAoY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHRoaXMucHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFKSB7XHJcbiAgICAgICAgICAgIHRvY1N0cnVjdHVyZS5wcmFjdGljZVRlc3QgKz0gMVxyXG4gICAgICAgICAgfSBlbHNlIGlmIChjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gdGhpcy5wcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCkge1xyXG4gICAgICAgICAgICB0b2NTdHJ1Y3R1cmUuZmluYWxUZXN0ICs9IDFcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGJyZWFrXHJcbiAgICAgICAgLy8gY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5XRUJfTU9EVUxFOlxyXG4gICAgICAgIC8vICAgdG9jU3RydWN0dXJlLndlYk1vZHVsZSArPSAxXHJcbiAgICAgICAgLy8gICBicmVha1xyXG4gICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuWklQMjpcclxuICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLlpJUDpcclxuICAgICAgICAgIHRvY1N0cnVjdHVyZS5pbnRlcmFjdGl2ZWNvbnRlbnQgKz0gMVxyXG4gICAgICAgICAgYnJlYWtcclxuICAgICAgICAvLyBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLllPVVRVQkU6XHJcbiAgICAgICAgLy8gICB0b2NTdHJ1Y3R1cmUueW91dHViZSArPSAxXHJcbiAgICAgICAgLy8gICBicmVha1xyXG4gICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICB0b2NTdHJ1Y3R1cmUub3RoZXIgKz0gMVxyXG4gICAgICAgICAgYnJlYWtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gdG9jU3RydWN0dXJlXHJcbiAgICB9XHJcbiAgICByZXR1cm4gdG9jU3RydWN0dXJlXHJcbiAgfVxyXG5cclxuICBmaWx0ZXJUb2MoXHJcbiAgICBjb250ZW50OiBOc0NvbnRlbnQuSUNvbnRlbnQsXHJcbiAgICBmaWx0ZXJDYXRlZ29yeTogTnNDb250ZW50LkVGaWx0ZXJDYXRlZ29yeSA9IE5zQ29udGVudC5FRmlsdGVyQ2F0ZWdvcnkuQUxMLFxyXG4gICk6IE5zQ29udGVudC5JQ29udGVudCB8IG51bGwge1xyXG4gICAgaWYgKGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5SRVNPVVJDRVxyXG4gICAgICAvLyAgfHwgY29udGVudC5jb250ZW50VHlwZSA9PT0gJ0tub3dsZWRnZSBBcnRpZmFjdCdcclxuICAgICAgfHwgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFXHJcbiAgICAgIHx8IGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5GSU5BTF9BU1NFU1NNRU5UXHJcbiAgICAgIHx8IGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5PRkZMSU5FX1NFU1NJT04pIHtcclxuICAgICAgcmV0dXJuIHRoaXMuZmlsdGVyVW5pdENvbnRlbnQoY29udGVudCwgZmlsdGVyQ2F0ZWdvcnkpID8gY29udGVudCA6IG51bGxcclxuICAgIH1cclxuICAgIGNvbnN0IGZpbHRlcmVkQ2hpbGRyZW46IE5zQ29udGVudC5JQ29udGVudFtdID1cclxuICAgICAgXy5tYXAoXy5nZXQoY29udGVudCwgJ2NoaWxkcmVuJyksIGNoaWxkQ29udGVudCA9PlxyXG4gICAgICAgIHRoaXMuZmlsdGVyVG9jKGNoaWxkQ29udGVudCwgZmlsdGVyQ2F0ZWdvcnkpKVxyXG4gICAgICAgIC5maWx0ZXIodW5pdENvbnRlbnQgPT4gQm9vbGVhbih1bml0Q29udGVudCkpIGFzIE5zQ29udGVudC5JQ29udGVudFtdXHJcbiAgICBpZiAoZmlsdGVyZWRDaGlsZHJlbiAmJiBmaWx0ZXJlZENoaWxkcmVuLmxlbmd0aCkge1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIC4uLmNvbnRlbnQsXHJcbiAgICAgICAgY2hpbGRyZW46IGZpbHRlcmVkQ2hpbGRyZW4sXHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBudWxsXHJcbiAgfVxyXG5cclxuICBmaWx0ZXJVbml0Q29udGVudChcclxuICAgIGNvbnRlbnQ6IE5zQ29udGVudC5JQ29udGVudCxcclxuICAgIGZpbHRlckNhdGVnb3J5OiBOc0NvbnRlbnQuRUZpbHRlckNhdGVnb3J5ID0gTnNDb250ZW50LkVGaWx0ZXJDYXRlZ29yeS5BTEwsXHJcbiAgKTogYm9vbGVhbiB7XHJcbiAgICBzd2l0Y2ggKGZpbHRlckNhdGVnb3J5KSB7XHJcbiAgICAgIGNhc2UgTnNDb250ZW50LkVGaWx0ZXJDYXRlZ29yeS5MRUFSTjpcclxuICAgICAgICByZXR1cm4gKFxyXG4gICAgICAgICAgIU5zQ29udGVudENvbnN0YW50cy5WQUxJRF9QUkFDVElDRV9SRVNPVVJDRVMuaGFzKGNvbnRlbnQucmVzb3VyY2VUeXBlKSAmJlxyXG4gICAgICAgICAgIU5zQ29udGVudENvbnN0YW50cy5WQUxJRF9BU1NFU1NNRU5UX1JFU09VUkNFUy5oYXMoY29udGVudC5yZXNvdXJjZVR5cGUpXHJcbiAgICAgICAgKVxyXG4gICAgICBjYXNlIE5zQ29udGVudC5FRmlsdGVyQ2F0ZWdvcnkuUFJBQ1RJQ0U6XHJcbiAgICAgICAgcmV0dXJuIE5zQ29udGVudENvbnN0YW50cy5WQUxJRF9QUkFDVElDRV9SRVNPVVJDRVMuaGFzKGNvbnRlbnQucmVzb3VyY2VUeXBlKVxyXG4gICAgICBjYXNlIE5zQ29udGVudC5FRmlsdGVyQ2F0ZWdvcnkuQVNTRVNTOlxyXG4gICAgICAgIHJldHVybiBOc0NvbnRlbnRDb25zdGFudHMuVkFMSURfQVNTRVNTTUVOVF9SRVNPVVJDRVMuaGFzKGNvbnRlbnQucmVzb3VyY2VUeXBlKVxyXG4gICAgICBjYXNlIE5zQ29udGVudC5FRmlsdGVyQ2F0ZWdvcnkuQUxMOlxyXG4gICAgICBkZWZhdWx0OlxyXG4gICAgICAgIHJldHVybiB0cnVlXHJcbiAgICB9XHJcbiAgfVxyXG4gIGZldGNoQ29udGVudEFuYWx5dGljc0NsaWVudERhdGEoY29udGVudElkOiBzdHJpbmcpIHtcclxuICAgIGlmICh0aGlzLmFuYWx5dGljc0ZldGNoU3RhdHVzICE9PSAnZmV0Y2hpbmcnICYmIHRoaXMuYW5hbHl0aWNzRmV0Y2hTdGF0dXMgIT09ICdkb25lJykge1xyXG4gICAgICB0aGlzLmdldENvbnRlbnRBbmFseXRpY3NDbGllbnQoY29udGVudElkKVxyXG4gICAgfVxyXG4gIH1cclxuICBwcml2YXRlIGdldENvbnRlbnRBbmFseXRpY3NDbGllbnQoY29udGVudElkOiBzdHJpbmcpIHtcclxuICAgIHRoaXMuYW5hbHl0aWNzRmV0Y2hTdGF0dXMgPSAnZmV0Y2hpbmcnXHJcbiAgICBjb25zdCB1cmwgPSBgJHtQUk9YWV9TTEFHX1Y4fS9MQS9hcGkvbGEvY29udGVudGFuYWx5dGljcz9jb250ZW50X2lkPSR7Y29udGVudElkfSZ0eXBlPWNvdXJzZWBcclxuICAgIHRoaXMuaHR0cC5nZXQodXJsKS5zdWJzY3JpYmUoXHJcbiAgICAgIChyZXN1bHQ6IGFueSkgPT4ge1xyXG4gICAgICAgIHRoaXMuYW5hbHl0aWNzRmV0Y2hTdGF0dXMgPSAnZG9uZSdcclxuICAgICAgICB0aGlzLmFuYWx5dGljc1JlcGxheVN1YmplY3QubmV4dChyZXN1bHQpXHJcbiAgICAgIH0sXHJcbiAgICAgICgpID0+IHtcclxuICAgICAgICB0aGlzLmFuYWx5dGljc1JlcGxheVN1YmplY3QubmV4dChudWxsKVxyXG4gICAgICAgIHRoaXMuYW5hbHl0aWNzRmV0Y2hTdGF0dXMgPSAnZG9uZSdcclxuICAgICAgfSxcclxuICAgIClcclxuICB9XHJcblxyXG4gIGZldGNoQ29udGVudEFuYWx5dGljc0RhdGEoY29udGVudElkOiBzdHJpbmcpIHtcclxuICAgIGlmICh0aGlzLmFuYWx5dGljc0ZldGNoU3RhdHVzICE9PSAnZmV0Y2hpbmcnICYmIHRoaXMuYW5hbHl0aWNzRmV0Y2hTdGF0dXMgIT09ICdkb25lJykge1xyXG4gICAgICB0aGlzLmdldENvbnRlbnRBbmFseXRpY3MoY29udGVudElkKVxyXG4gICAgfVxyXG4gIH1cclxuICBwcml2YXRlIGdldENvbnRlbnRBbmFseXRpY3MoY29udGVudElkOiBzdHJpbmcpIHtcclxuICAgIHRoaXMuYW5hbHl0aWNzRmV0Y2hTdGF0dXMgPSAnZmV0Y2hpbmcnXHJcbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6IG1heC1saW5lLWxlbmd0aFxyXG4gICAgY29uc3QgdXJsID0gYCR7UFJPWFlfU0xBR19WOH0vTEEvTEEvYXBpL1VzZXJzP3JlZmluZW1lbnRmaWx0ZXI9JHtlbmNvZGVVUklDb21wb25lbnQoXHJcbiAgICAgICdcInNvdXJjZVwiOltcImlHb3RcIixcIkxlYXJuaW5nIEh1YlwiXScsXHJcbiAgICApfSQke2VuY29kZVVSSUNvbXBvbmVudChgXCJjb3Vyc2VDb2RlXCI6IFtcIiR7Y29udGVudElkfVwiXWApfWBcclxuICAgIHRoaXMuaHR0cC5nZXQodXJsKS5zdWJzY3JpYmUoXHJcbiAgICAgIChyZXN1bHQ6IGFueSkgPT4ge1xyXG4gICAgICAgIHRoaXMuYW5hbHl0aWNzRmV0Y2hTdGF0dXMgPSAnZG9uZSdcclxuICAgICAgICB0aGlzLmFuYWx5dGljc1JlcGxheVN1YmplY3QubmV4dChyZXN1bHQpXHJcbiAgICAgIH0sXHJcbiAgICAgICgpID0+IHtcclxuICAgICAgICB0aGlzLmFuYWx5dGljc1JlcGxheVN1YmplY3QubmV4dChudWxsKVxyXG4gICAgICAgIHRoaXMuYW5hbHl0aWNzRmV0Y2hTdGF0dXMgPSAnZG9uZSdcclxuICAgICAgfSxcclxuICAgIClcclxuICB9XHJcblxyXG4gIGNsZWFyQW5hbHl0aWNzRGF0YSgpIHtcclxuICAgIGlmICh0aGlzLmFuYWx5dGljc1JlcGxheVN1YmplY3QpIHtcclxuICAgICAgdGhpcy5hbmFseXRpY3NSZXBsYXlTdWJqZWN0LnVuc3Vic2NyaWJlKClcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlc2V0IGhhc2htYXAgYW5kIHJlbGF0ZWQgY29udGVudCBkYXRhXHJcbiAgICogQ2FsbCB0aGlzIHdoZW4gbmF2aWdhdGluZyBhd2F5IGZyb20gY29udGVudCB0byBwcmV2ZW50IHN0YWxlIGRhdGFcclxuICAgKi9cclxuICByZXNldENvbnRlbnREYXRhKCkge1xyXG4gICAgdGhpcy5oYXNobWFwID0ge31cclxuICAgIHRoaXMuaGFzaG1hcFVwZGF0ZWQubmV4dChudWxsKVxyXG4gICAgY29uc29sZS5sb2coJ0NvbnRlbnQgZGF0YSBjbGVhcmVkIC0gaGFzaG1hcCByZXNldCcpXHJcbiAgfVxyXG5cclxuICBmZXRjaENvbnRlbnRQYXJlbnRzKGNvbnRlbnRJZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxOc0NvbnRlbnQuSUNvbnRlbnRNaW5pbWFsW10+IHtcclxuICAgIC8vIHJldHVybiB0aGlzLmh0dHAuZ2V0PE5zQ29udGVudC5JQ29udGVudE1pbmltYWxbXT4oXHJcbiAgICAvLyAgIGAke0FQSV9FTkRfUE9JTlRTLkNPTlRFTlRfUEFSRU5UU30vJHtjb250ZW50SWR9YCxcclxuICAgIC8vIClcclxuICAgIGlmIChjb250ZW50SWQpIHsgfVxyXG4gICAgcmV0dXJuIEVNUFRZXHJcbiAgfVxyXG4gIGZldGNoQ29udGVudFdoYXRzTmV4dChcclxuICAgIGNvbnRlbnRJZDogc3RyaW5nLFxyXG4gICAgY29udGVudFR5cGU/OiBzdHJpbmcsXHJcbiAgKTogT2JzZXJ2YWJsZTxOc0NvbnRlbnQuSUNvbnRlbnRNaW5pbWFsW10+IHtcclxuICAgIGlmIChjb250ZW50VHlwZSkge1xyXG4gICAgICByZXR1cm4gdGhpcy5odHRwLmdldDxOc0NvbnRlbnQuSUNvbnRlbnRNaW5pbWFsW10+KFxyXG4gICAgICAgIGAke0FQSV9FTkRfUE9JTlRTLkNPTlRFTlRfTkVYVH0vJHtjb250ZW50SWR9P2NvbnRlbnRUeXBlPSR7Y29udGVudFR5cGV9YCxcclxuICAgICAgKVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8TnNDb250ZW50LklDb250ZW50TWluaW1hbFtdPihcclxuICAgICAgYCR7QVBJX0VORF9QT0lOVFMuQ09OVEVOVF9ORVhUfS8ke2NvbnRlbnRJZH0/dHM9JHtuZXcgRGF0ZSgpLmdldFRpbWUoKX1gLFxyXG4gICAgKVxyXG4gIH1cclxuXHJcbiAgZmV0Y2hNb3JlTGlrZVRoaXNQYWlkKGNvbnRlbnRJZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxOc0NvbnRlbnQuSUNvbnRlbnRNaW5pbWFsW10+IHtcclxuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PE5zQ29udGVudC5JQ29udGVudE1pbmltYWxbXT4oXHJcbiAgICAgIGAke0FQSV9FTkRfUE9JTlRTLkNPTlRFTlRfTkVYVFxyXG4gICAgICB9LyR7Y29udGVudElkfT9leGNsdXNpdmVDb250ZW50PXRydWUmdHM9JHtuZXcgRGF0ZSgpLmdldFRpbWUoKX1gLFxyXG4gICAgKVxyXG4gIH1cclxuXHJcbiAgZmV0Y2hNb3JlTGlrZVRoaXNGcmVlKGNvbnRlbnRJZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxOc0NvbnRlbnQuSUNvbnRlbnRNaW5pbWFsW10+IHtcclxuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PE5zQ29udGVudC5JQ29udGVudE1pbmltYWxbXT4oXHJcbiAgICAgIGAke0FQSV9FTkRfUE9JTlRTLkNPTlRFTlRfTkVYVFxyXG4gICAgICB9LyR7Y29udGVudElkfT9leGNsdXNpdmVDb250ZW50PWZhbHNlJnRzPSR7bmV3IERhdGUoKS5nZXRUaW1lKCl9YCxcclxuICAgIClcclxuICB9XHJcblxyXG4gIGZldGNoQ29udGVudENvaG9ydHMoXHJcbiAgICBjb2hvcnRUeXBlOiBOc0NvaG9ydHMuRUNvaG9ydFR5cGVzLFxyXG4gICAgY29udGVudElkOiBzdHJpbmcsXHJcbiAgKTogT2JzZXJ2YWJsZTxOc0NvaG9ydHMuSUNvaG9ydHNDb250ZW50W10+IHtcclxuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PE5zQ29ob3J0cy5JQ29ob3J0c0NvbnRlbnRbXT4oQVBJX0VORF9QT0lOVFMuQ09IT1JUUyhjb2hvcnRUeXBlLCBjb250ZW50SWQpLCB7XHJcbiAgICAgIGhlYWRlcnM6IHsgcm9vdE9yZzogdGhpcy5jb25maWdTdmMucm9vdE9yZyB8fCAnJywgb3JnOiB0aGlzLmNvbmZpZ1N2Yy5vcmcgPyB0aGlzLmNvbmZpZ1N2Yy5vcmdbMF0gOiAnJyB9LFxyXG4gICAgfSlcclxuICB9XHJcbiAgZmV0Y2hFeHRlcm5hbENvbnRlbnRBY2Nlc3MoY29udGVudElkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPHsgaGFzQWNjZXNzOiBib29sZWFuIH0+IHtcclxuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PHsgaGFzQWNjZXNzOiBib29sZWFuIH0+KEFQSV9FTkRfUE9JTlRTLkVYVEVSTkFMX0NPTlRFTlQoY29udGVudElkKSlcclxuICB9XHJcbiAgZmV0Y2hDb2hvcnRHcm91cFVzZXJzKGdyb3VwSWQ6IG51bWJlcikge1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8TnNDb2hvcnRzLklDb2hvcnRzR3JvdXBVc2Vyc1tdPihBUElfRU5EX1BPSU5UUy5DT0hPUlRTX0dST1VQX1VTRVIoZ3JvdXBJZCkpXHJcbiAgfVxyXG4gIGZldGNoTW9yZUxpa2VUaGlzKGNvbnRlbnRJZDogc3RyaW5nLCBjb250ZW50VHlwZTogc3RyaW5nKTogT2JzZXJ2YWJsZTxhbnk+IHtcclxuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PE5zQ29udGVudC5JQ29udGVudFtdPihcclxuICAgICAgQVBJX0VORF9QT0lOVFMuUkVMQVRFRF9SRVNPVVJDRShjb250ZW50SWQsIGNvbnRlbnRUeXBlKSxcclxuICAgIClcclxuICB9XHJcblxyXG4gIGZldGNoUG9zdEFzc2Vzc21lbnRTdGF0dXMoY29udGVudElkOiBzdHJpbmcpIHtcclxuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PHsgcmVzdWx0OiBOc0FwcFRvYy5JUG9zdEFzc2Vzc21lbnRbXSB9PihcclxuICAgICAgQVBJX0VORF9QT0lOVFMuUE9TVF9BU1NFU1NNRU5UKGNvbnRlbnRJZCksXHJcbiAgICApXHJcbiAgfVxyXG5cclxuICBmZXRjaEdldENvbnRlbnREYXRhKGNvbnRlbnRJZDogc3RyaW5nKSB7XHJcbiAgICBsZXQgdXJsID0gJydcclxuICAgIGNvbnN0IGZvclByZXZpZXcgPSB3aW5kb3cubG9jYXRpb24uaHJlZi5pbmNsdWRlcygnL3B1YmxpYy8nKSB8fCB3aW5kb3cubG9jYXRpb24uaHJlZi5pbmNsdWRlcygnJnByZXZpZXc9dHJ1ZScpXHJcbiAgICBpZiAoIWZvclByZXZpZXcpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8eyByZXN1bHQ6IGFueSB9PihcclxuICAgICAgICBBUElfRU5EX1BPSU5UUy5HRVRfQ09OVEVOVChjb250ZW50SWQpLFxyXG4gICAgICApXHJcbiAgICB9XHJcbiAgICBpZiAod2luZG93LmxvY2F0aW9uLmhyZWYuaW5jbHVkZXMoJ2VkaXRNb2RlPXRydWUnKSAmJiB3aW5kb3cubG9jYXRpb24uaHJlZi5pbmNsdWRlcygnX3JjJykpIHtcclxuICAgICAgdXJsID0gYC9hcGlzL3Byb3hpZXMvdjgvYWN0aW9uL2NvbnRlbnQvdjMvcmVhZC8ke2NvbnRlbnRJZH1gXHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB1cmwgPSBgL2FwaS9jb250ZW50L3YxL3JlYWQvJHtjb250ZW50SWR9YFxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8eyByZXN1bHQ6IGFueSB9Pih1cmwpXHJcblxyXG4gIH1cclxuXHJcbiAgZmV0Y2hDb250ZW50UGFyZW50KGNvbnRlbnRJZDogc3RyaW5nLCBkYXRhOiBOc0FwcFRvYy5JQ29udGVudFBhcmVudFJlcSwgZm9yUHJldmlldyA9IGZhbHNlKSB7XHJcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3Q8TnNBcHBUb2MuSUNvbnRlbnRQYXJlbnRSZXNwb25zZT4oXHJcbiAgICAgIGZvclByZXZpZXdcclxuICAgICAgICA/IEFQSV9FTkRfUE9JTlRTLkNPTlRFTlRfQVVUSF9QQVJFTlQoXHJcbiAgICAgICAgICBjb250ZW50SWQsXHJcbiAgICAgICAgICB0aGlzLmNvbmZpZ1N2Yy5yb290T3JnIHx8ICcnLFxyXG4gICAgICAgICAgdGhpcy5jb25maWdTdmMub3JnID8gdGhpcy5jb25maWdTdmMub3JnWzBdIDogJycsXHJcbiAgICAgICAgKVxyXG4gICAgICAgIDogQVBJX0VORF9QT0lOVFMuQ09OVEVOVF9QQVJFTlQoY29udGVudElkKSxcclxuICAgICAgZGF0YSxcclxuICAgIClcclxuICB9XHJcblxyXG4gIGNyZWF0ZUJhdGNoKGJhdGNoRGF0YTogYW55KSB7XHJcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3QoXHJcbiAgICAgIEFQSV9FTkRfUE9JTlRTLkJBVENIX0NSRUFURSxcclxuICAgICAgeyByZXF1ZXN0OiBiYXRjaERhdGEgfSxcclxuICAgIClcclxuICB9XHJcblxyXG4gIGFzeW5jIG1hcENvbXBsZXRpb25QZXJjZW50YWdlUHJvZ3JhbShjb250ZW50OiBOc0NvbnRlbnQuSUNvbnRlbnQgfCBudWxsLCBlbnJvbG1lbnRMaXN0OiBhbnksIGNvbGxlY3Rpb25JZD86IHN0cmluZykge1xyXG4gICAgdGhpcy5jb250ZW50TG9hZGVyLm5leHQodHJ1ZSlcclxuICAgIGxldCB0b3RhbENvdW50ID0gMFxyXG4gICAgbGV0IGxlYWZub2RlQ291bnQgPSAwXHJcbiAgICBsZXQgY29tcGxldGVkTGVhZk5vZGVzOiBhbnkgPSBbXVxyXG4gICAgbGV0IGZpcnN0VW5jb21wbGV0ZUNvdXJzZTogYW55ID0gJydcclxuICAgIGxldCBpbnByb2dyZXNzRGF0YUNoZWNrOiBhbnkgPSBbXVxyXG4gICAgaWYgKGNvbnRlbnQgJiYgY29udGVudC5jaGlsZHJlbikge1xyXG4gICAgICBsZWFmbm9kZUNvdW50ID0gY29udGVudC5sZWFmTm9kZXNDb3VudFxyXG4gICAgICB0aGlzLmNvbnRlbnRMb2FkZXIubmV4dCh0cnVlKVxyXG4gICAgICBjb25zdCBmb3VuZFBhcmVudENvbnRlbnQgPSB0aGlzLmZpbmRFbnJvbG1lbnRCeUNvbGxlY3Rpb25JZChlbnJvbG1lbnRMaXN0LCBjb2xsZWN0aW9uSWQgfHwgY29udGVudC5pZGVudGlmaWVyKVxyXG4gICAgICBpZiAoZm91bmRQYXJlbnRDb250ZW50ICYmIGZvdW5kUGFyZW50Q29udGVudC5jb21wbGV0aW9uUGVyY2VudGFnZSA9PT0gMTAwKSB7XHJcbiAgICAgICAgYXdhaXQgdGhpcy5tYXBDb21wbGV0aW9uQ2hpbGRQZXJjZW50YWdlUHJvZ3JhbShjb250ZW50KVxyXG4gICAgICAgIHRvdGFsQ291bnQgPSBjb250ZW50LmxlYWZOb2Rlc0NvdW50XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgaWYgKGNvbnRlbnQ/LnByaW1hcnlDYXRlZ29yeSAhPT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuQ09VUlNFKSB7XHJcbiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbnRlbnQuY2hpbGRyZW4ubGVuZ3RoOyBpICs9IDEpIHtcclxuICAgICAgICAgICAgLy8gY29udGVudC5jaGlsZHJlbi5mb3JFYWNoKGFzeW5jIChwYXJlbnRDaGlsZCxpbmRleCkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBwYXJlbnRDaGlsZCA9IGNvbnRlbnQuY2hpbGRyZW5baV1cclxuICAgICAgICAgICAgaWYgKHBhcmVudENoaWxkLnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuQ09VUlNFKSB7XHJcbiAgICAgICAgICAgICAgY29uc3QgZm91bmRDb250ZW50ID0gdGhpcy5maW5kRW5yb2xtZW50QnlDb2xsZWN0aW9uSWQoZW5yb2xtZW50TGlzdCwgcGFyZW50Q2hpbGQ/LmlkZW50aWZpZXIpXHJcbiAgICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOiBtYXgtbGluZS1sZW5ndGhcclxuICAgICAgICAgICAgICAvLyB0b3RhbENvdW50ID0gZm91bmRDb250ZW50ICYmIGZvdW5kQ29udGVudC5jb21wbGV0aW9uUGVyY2VudGFnZSA/IHRvdGFsQ291bnQgKyBmb3VuZENvbnRlbnQuY29tcGxldGlvblBlcmNlbnRhZ2UgOiB0b3RhbENvdW50ICsgMFxyXG4gICAgICAgICAgICAgIC8vIGNvbnRlbnQuY29tcGxldGlvblBlcmNlbnRhZ2UgPSBNYXRoLnJvdW5kKHRvdGFsQ291bnQgLyBsZWFmbm9kZUNvdW50KVxyXG4gICAgICAgICAgICAgIGlmIChmb3VuZENvbnRlbnQgJiYgZm91bmRDb250ZW50LmNvbXBsZXRpb25QZXJjZW50YWdlID09PSAxMDApIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY29udGVudExvYWRlci5uZXh0KHRydWUpXHJcbiAgICAgICAgICAgICAgICB0b3RhbENvdW50ID0gdG90YWxDb3VudCArPSBwYXJlbnRDaGlsZC5sZWFmTm9kZXNDb3VudFxyXG4gICAgICAgICAgICAgICAgY29tcGxldGVkTGVhZk5vZGVzID0gWy4uLmNvbXBsZXRlZExlYWZOb2RlcywgLi4ucGFyZW50Q2hpbGQubGVhZk5vZGVzXVxyXG4gICAgICAgICAgICAgICAgaWYgKGZvdW5kQ29udGVudC5pc3N1ZWRDZXJ0aWZpY2F0ZXMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICBjb25zdCBjZXJ0aWZpY2F0ZTogYW55ID0gZm91bmRDb250ZW50Lmlzc3VlZENlcnRpZmljYXRlcy5zb3J0KChhOiBhbnksIGI6IGFueSkgPT5cclxuICAgICAgICAgICAgICAgICAgICBuZXcgRGF0ZShhLmxhc3RJc3N1ZWRPbikuZ2V0VGltZSgpIC0gbmV3IERhdGUoYi5sYXN0SXNzdWVkT24pLmdldFRpbWUoKSlcclxuICAgICAgICAgICAgICAgICAgY29uc3QgY2VydElkOiBhbnkgPSBjZXJ0aWZpY2F0ZVswXS5pZGVudGlmaWVyXHJcbiAgICAgICAgICAgICAgICAgIHBhcmVudENoaWxkLmlzc3VlZENlcnRpZmljYXRlc0lkID0gY2VydElkXHJcbiAgICAgICAgICAgICAgICAgIC8vIGNvbnN0IGNlcnREYXRhOiBhbnkgPSBhd2FpdCB0aGlzLmRvd29ubG9hZENlcnRpZmljYXRlKGNlcnRJZCkudG9Qcm9taXNlKCkuY2F0Y2goX2Vycm9yID0+IHtcclxuICAgICAgICAgICAgICAgICAgLy8gICB0aGlzLmNvbnRlbnRMb2FkZXIubmV4dChmYWxzZSlcclxuICAgICAgICAgICAgICAgICAgLy8gfSlcclxuICAgICAgICAgICAgICAgICAgLy8gaWYgKGNlcnREYXRhICYmIGNlcnREYXRhLnJlc3VsdCkge1xyXG4gICAgICAgICAgICAgICAgICAvLyAgIHBhcmVudENoaWxkLmlzc3VlZENlcnRpZmljYXRlc1NWRyA9IGNlcnREYXRhLnJlc3VsdC5wcmludFVyaVxyXG4gICAgICAgICAgICAgICAgICAvLyB9XHJcbiAgICAgICAgICAgICAgICAgIHRoaXMuY29udGVudExvYWRlci5uZXh0KGZhbHNlKVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcGFyZW50Q2hpbGQuY29tcGxldGlvblBlcmNlbnRhZ2UgPSAxMDBcclxuICAgICAgICAgICAgICAgIHBhcmVudENoaWxkLmNvbXBsZXRpb25TdGF0dXMgPSAyXHJcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLm1hcENvbXBsZXRpb25DaGlsZFBlcmNlbnRhZ2VQcm9ncmFtKHBhcmVudENoaWxkKVxyXG4gICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZm91bmRDb250ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgIHRoaXMuY29udGVudExvYWRlci5uZXh0KHRydWUpXHJcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGxhbmd1YWdlID0gdGhpcy5jb250ZW50TGFuZ1N2Yy5nZXRDb250ZW50TGFuZ3VhZ2UocGFyZW50Q2hpbGQpXHJcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHJlcSA9IHtcclxuICAgICAgICAgICAgICAgICAgICByZXF1ZXN0OiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICBiYXRjaElkOiBmb3VuZENvbnRlbnQuYmF0Y2guYmF0Y2hJZCxcclxuICAgICAgICAgICAgICAgICAgICAgIHVzZXJJZDogZm91bmRDb250ZW50LnVzZXJJZCxcclxuICAgICAgICAgICAgICAgICAgICAgIGxhbmd1YWdlOiBsYW5ndWFnZSxcclxuICAgICAgICAgICAgICAgICAgICAgIGNvdXJzZUlkOiBmb3VuZENvbnRlbnQuY29sbGVjdGlvbklkLFxyXG4gICAgICAgICAgICAgICAgICAgICAgY29udGVudElkczogW10sXHJcbiAgICAgICAgICAgICAgICAgICAgICBmaWVsZHM6IFtcclxuICAgICAgICAgICAgICAgICAgICAgICAgJ3Byb2dyZXNzZGV0YWlscycsXHJcbiAgICAgICAgICAgICAgICAgICAgICBdLFxyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgZmlyc3RVbmNvbXBsZXRlQ291cnNlID0gKHBhcmVudENoaWxkLmNvbXBsZXRpb25QZXJjZW50YWdlID09PSAwIHx8ICFwYXJlbnRDaGlsZC5jb21wbGV0aW9uUGVyY2VudGFnZSkgJiZcclxuICAgICAgICAgICAgICAgICAgICAhZmlyc3RVbmNvbXBsZXRlQ291cnNlID8gcGFyZW50Q2hpbGQgOiBmaXJzdFVuY29tcGxldGVDb3Vyc2VcclxuICAgICAgICAgICAgICAgICAgaW5wcm9ncmVzc0RhdGFDaGVjayA9IGlucHJvZ3Jlc3NEYXRhQ2hlY2tcclxuICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5mZXRjaENvbnRlbnRIaXN0b3J5VjIocmVxKS50b1Byb21pc2UoKS50aGVuKChwcm9ncmVzc2RhdGE6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGRhdGE6IGFueSA9IHByb2dyZXNzZGF0YVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChkYXRhLnJlc3VsdCAmJiBkYXRhPy5yZXN1bHQ/LmNvbnRlbnRMaXN0Py5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb21wbGV0ZWRDb3VudCA9IGRhdGEucmVzdWx0LmNvbnRlbnRMaXN0LmZpbHRlcigoZWxlOiBhbnkpID0+IGVsZS5wcm9ncmVzcyA9PT0gMTAwKVxyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5jaGVja0NvbXBsZXRlZExlYWZub2Rlcyhjb21wbGV0ZWRMZWFmTm9kZXMsIGNvbXBsZXRlZENvdW50KVxyXG4gICAgICAgICAgICAgICAgICAgICAgdG90YWxDb3VudCA9IGNvbXBsZXRlZExlYWZOb2Rlcy5sZW5ndGhcclxuICAgICAgICAgICAgICAgICAgICAgIGlucHJvZ3Jlc3NEYXRhQ2hlY2sgPSBbLi4uaW5wcm9ncmVzc0RhdGFDaGVjaywgLi4uZGF0YS5yZXN1bHQuY29udGVudExpc3RdXHJcbiAgICAgICAgICAgICAgICAgICAgICAvLyBpbnByb2dyZXNzRGF0YUNoZWNrID0gaW5wcm9ncmVzc0RhdGFDaGVjayA/IGlucHJvZ3Jlc3NEYXRhQ2hlY2sgOiAgZGF0YS5yZXN1bHQuY29udGVudExpc3RcclxuICAgICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlUmVzdW1hRGF0YShpbnByb2dyZXNzRGF0YUNoZWNrKVxyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5tYXBDb21wbGV0aW9uUGVyY2VudGFnZShwYXJlbnRDaGlsZCwgZGF0YS5yZXN1bHQuY29udGVudExpc3QpXHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hcE1vZHVsZUNvdW50KHBhcmVudENoaWxkKVxyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hcE1vZHVsZUNvdW50KHBhcmVudENoaWxkKVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcHJvZ3Jlc3NkYXRhXHJcbiAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICAgIHRoaXMuY29udGVudExvYWRlci5uZXh0KGZhbHNlKVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyAgZWxzZSB7XHJcbiAgICAgICAgICAgIC8vICAgaWYgKGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ICE9PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5CTEVOREVEX1BST0dSQU0pIHtcclxuICAgICAgICAgICAgLy8gICAgIHRoaXMuY29udGVudExvYWRlci5uZXh0KHRydWUpXHJcbiAgICAgICAgICAgIC8vICAgICBjb25zdCBmb3VuZENvbnRlbnQgPSBlbnJvbG1lbnRMaXN0ICYmIGVucm9sbWVudExpc3QuZmluZCgoZWw6IGFueSkgPT4gZWwuY29sbGVjdGlvbklkID09PSBjb250ZW50LmlkZW50aWZpZXIpXHJcbiAgICAgICAgICAgIC8vICAgICBpZiAoZm91bmRDb250ZW50KSB7XHJcbiAgICAgICAgICAgIC8vICAgICAgIGNvbnN0IHJlcSA9IHtcclxuICAgICAgICAgICAgLy8gICAgICAgICByZXF1ZXN0OiB7XHJcbiAgICAgICAgICAgIC8vICAgICAgICAgICBiYXRjaElkOiBmb3VuZENvbnRlbnQuYmF0Y2guYmF0Y2hJZCxcclxuICAgICAgICAgICAgLy8gICAgICAgICAgIHVzZXJJZDogZm91bmRDb250ZW50LnVzZXJJZCxcclxuICAgICAgICAgICAgLy8gICAgICAgICAgIGNvdXJzZUlkOiBmb3VuZENvbnRlbnQuY29sbGVjdGlvbklkLFxyXG4gICAgICAgICAgICAvLyAgICAgICAgICAgY29udGVudElkczogW10sXHJcbiAgICAgICAgICAgIC8vICAgICAgICAgICBmaWVsZHM6IFtcclxuICAgICAgICAgICAgLy8gICAgICAgICAgICAgJ3Byb2dyZXNzZGV0YWlscycsXHJcbiAgICAgICAgICAgIC8vICAgICAgICAgICBdLFxyXG4gICAgICAgICAgICAvLyAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIC8vICAgICAgIH1cclxuICAgICAgICAgICAgLy8gICAgICAgYXdhaXQgdGhpcy5mZXRjaENvbnRlbnRIaXN0b3J5VjIocmVxKS50b1Byb21pc2UoKS50aGVuKChwcm9ncmVzc2RhdGE6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAvLyAgICAgICAgIGNvbnN0IGRhdGE6IGFueSAgPSBwcm9ncmVzc2RhdGFcclxuICAgICAgICAgICAgLy8gICAgICAgICBpZiAoZGF0YS5yZXN1bHQgJiYgZGF0YS5yZXN1bHQuY29udGVudExpc3QubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAvLyAgICAgICAgICAgY29uc3QgY29tcGxldGVkQ291bnQgPSBkYXRhLnJlc3VsdC5jb250ZW50TGlzdC5maWx0ZXIoKGVsZTogYW55KSA9PiBlbGUucHJvZ3Jlc3MgPT09IDEwMClcclxuICAgICAgICAgICAgLy8gICAgICAgICAgIHRoaXMuY2hlY2tDb21wbGV0ZWRMZWFmbm9kZXMoY29tcGxldGVkTGVhZk5vZGVzLCBjb21wbGV0ZWRDb3VudClcclxuICAgICAgICAgICAgLy8gICAgICAgICAgIHRvdGFsQ291bnQgPSBjb21wbGV0ZWRMZWFmTm9kZXMubGVuZ3RoXHJcbiAgICAgICAgICAgIC8vICAgICAgICAgICBpbnByb2dyZXNzRGF0YUNoZWNrID0gaW5wcm9ncmVzc0RhdGFDaGVjayA/IGlucHJvZ3Jlc3NEYXRhQ2hlY2sgOiAgZGF0YS5yZXN1bHQuY29udGVudExpc3RcclxuICAgICAgICAgICAgLy8gICAgICAgICAgIHRoaXMudXBkYXRlUmVzdW1hRGF0YShpbnByb2dyZXNzRGF0YUNoZWNrKVxyXG4gICAgICAgICAgICAvLyAgICAgICAgICAgdGhpcy5tYXBDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50LCBkYXRhLnJlc3VsdC5jb250ZW50TGlzdClcclxuICAgICAgICAgICAgLy8gICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vICAgICAgICAgdGhpcy5jb250ZW50TG9hZGVyLm5leHQoZmFsc2UpXHJcbiAgICAgICAgICAgIC8vICAgICAgICAgcmV0dXJuIHByb2dyZXNzZGF0YVxyXG4gICAgICAgICAgICAvLyAgICAgICB9KVxyXG4gICAgICAgICAgICAvLyAgICAgfVxyXG4gICAgICAgICAgICAvLyAgICAgdGhpcy5jb250ZW50TG9hZGVyLm5leHQoZmFsc2UpXHJcbiAgICAgICAgICAgIC8vICAgfVxyXG4gICAgICAgICAgICAvLyB9XHJcbiAgICAgICAgICAgIHRoaXMuY29udGVudExvYWRlci5uZXh0KGZhbHNlKVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LkJMRU5ERURfUFJPR1JBTVxyXG4gICAgICAgICAgfHwgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LkNPVVJTRVxyXG4gICAgICAgICAgfHwgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LlNUQU5EQUxPTkVfQVNTRVNTTUVOVFxyXG4gICAgICAgICAgfHwgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LkNVUkFURURfUFJPR1JBTSkge1xyXG4gICAgICAgICAgLy8gdGhpcy5tYXBDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50LCB0aGlzLnJlc3VtZURhdGEpXHJcbiAgICAgICAgICBjb25zdCBmb3VuZFBhcmVudENvbnRlbnQgPSB0aGlzLmZpbmRFbnJvbG1lbnRCeUNvbGxlY3Rpb25JZChlbnJvbG1lbnRMaXN0LCBjb2xsZWN0aW9uSWQgfHwgY29udGVudD8uaWRlbnRpZmllcilcclxuICAgICAgICAgIGNvbnN0IGxhbmd1YWdlID0gdGhpcy5jb250ZW50TGFuZ1N2Yy5nZXRDb250ZW50TGFuZ3VhZ2UoY29udGVudClcclxuICAgICAgICAgIGNvbnN0IHJlcSA9IHtcclxuICAgICAgICAgICAgcmVxdWVzdDoge1xyXG4gICAgICAgICAgICAgIGJhdGNoSWQ6IGZvdW5kUGFyZW50Q29udGVudD8uYmF0Y2g/LmJhdGNoSWQsXHJcbiAgICAgICAgICAgICAgdXNlcklkOiBmb3VuZFBhcmVudENvbnRlbnQ/LnVzZXJJZCxcclxuICAgICAgICAgICAgICBjb3Vyc2VJZDogZm91bmRQYXJlbnRDb250ZW50Py5jb2xsZWN0aW9uSWQsXHJcbiAgICAgICAgICAgICAgbGFuZ3VhZ2U6IGxhbmd1YWdlLFxyXG4gICAgICAgICAgICAgIGNvbnRlbnRJZHM6IFtdLFxyXG4gICAgICAgICAgICAgIGZpZWxkczogW1xyXG4gICAgICAgICAgICAgICAgJ3Byb2dyZXNzZGV0YWlscycsXHJcbiAgICAgICAgICAgICAgXSxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGF3YWl0IHRoaXMuZmV0Y2hDb250ZW50SGlzdG9yeVYyKHJlcSkudG9Qcm9taXNlKCkudGhlbigocHJvZ3Jlc3NkYXRhOiBhbnkpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgZGF0YTogYW55ID0gcHJvZ3Jlc3NkYXRhXHJcbiAgICAgICAgICAgIGlmIChkYXRhICYmIGRhdGEucmVzdWx0ICYmIGRhdGEucmVzdWx0LmNvbnRlbnRMaXN0Lmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICBjb25zdCBjb21wbGV0ZWRDb3VudCA9IGRhdGEucmVzdWx0LmNvbnRlbnRMaXN0LmZpbHRlcigoZWxlOiBhbnkpID0+IGVsZS5wcm9ncmVzcyA9PT0gMTAwKVxyXG4gICAgICAgICAgICAgIHRoaXMuY2hlY2tDb21wbGV0ZWRMZWFmbm9kZXMoY29tcGxldGVkTGVhZk5vZGVzLCBjb21wbGV0ZWRDb3VudClcclxuICAgICAgICAgICAgICB0b3RhbENvdW50ID0gY29tcGxldGVkTGVhZk5vZGVzLmxlbmd0aFxyXG4gICAgICAgICAgICAgIGlucHJvZ3Jlc3NEYXRhQ2hlY2sgPSBbLi4uaW5wcm9ncmVzc0RhdGFDaGVjaywgLi4uZGF0YS5yZXN1bHQuY29udGVudExpc3RdXHJcbiAgICAgICAgICAgICAgLy8gaW5wcm9ncmVzc0RhdGFDaGVjayA9IGlucHJvZ3Jlc3NEYXRhQ2hlY2sgPyBpbnByb2dyZXNzRGF0YUNoZWNrIDogIGRhdGEucmVzdWx0LmNvbnRlbnRMaXN0XHJcbiAgICAgICAgICAgICAgdGhpcy51cGRhdGVSZXN1bWFEYXRhKGlucHJvZ3Jlc3NEYXRhQ2hlY2spXHJcbiAgICAgICAgICAgICAgdGhpcy5tYXBDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50LCBkYXRhLnJlc3VsdC5jb250ZW50TGlzdClcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLmNvbnRlbnRMb2FkZXIubmV4dChmYWxzZSlcclxuICAgICAgICAgICAgcmV0dXJuIHByb2dyZXNzZGF0YVxyXG4gICAgICAgICAgfSlcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChpbnByb2dyZXNzRGF0YUNoZWNrICYmIGlucHJvZ3Jlc3NEYXRhQ2hlY2subGVuZ3RoID09PSAwICYmIGZpcnN0VW5jb21wbGV0ZUNvdXJzZSkge1xyXG4gICAgICAgICAgY29uc3QgZmlyc3RDaGlsZERhdGEgPSB0aGlzLndpZGdldFN2Yy5nZXRGaXJzdENoaWxkSW5IaWVyYXJjaHkoZmlyc3RVbmNvbXBsZXRlQ291cnNlKVxyXG4gICAgICAgICAgY29uc3QgY2hpbGRFbnJvbGxtZW50RGF0YSA9IGVucm9sbWVudExpc3QuZmluZCgoZWw6IGFueSkgPT5cclxuICAgICAgICAgICAgZWwuY29sbGVjdGlvbklkID09PSBmaXJzdFVuY29tcGxldGVDb3Vyc2UuaWRlbnRpZmllcilcclxuICAgICAgICAgIGNvbnN0IHJlc3VtZURhdGEgPSBbe1xyXG4gICAgICAgICAgICBjb250ZW50SWQ6IGZpcnN0Q2hpbGREYXRhLmlkZW50aWZpZXIsXHJcbiAgICAgICAgICAgIGJhdGNoSWQ6IGNoaWxkRW5yb2xsbWVudERhdGEgJiYgY2hpbGRFbnJvbGxtZW50RGF0YS5iYXRjaElkLFxyXG4gICAgICAgICAgICBjb21wbGV0ZWRDb3VudDogMSxcclxuICAgICAgICAgICAgY29tcGxldGlvblBlcmNlbnRhZ2U6IDAuMCxcclxuICAgICAgICAgICAgcHJvZ3Jlc3M6IDAsXHJcbiAgICAgICAgICAgIHZpZXdDb3VudDogMSxcclxuICAgICAgICAgICAgY291cnNlSWQ6IGNoaWxkRW5yb2xsbWVudERhdGEgJiYgY2hpbGRFbnJvbGxtZW50RGF0YS5jb3Vyc2VJZCxcclxuICAgICAgICAgICAgY29sbGVjdGlvbklkOiBjaGlsZEVucm9sbG1lbnREYXRhICYmIGNoaWxkRW5yb2xsbWVudERhdGEuY291cnNlSWQsXHJcbiAgICAgICAgICAgIHN0YXR1czogMSxcclxuICAgICAgICAgIH1dXHJcbiAgICAgICAgICBpbnByb2dyZXNzRGF0YUNoZWNrID0gcmVzdW1lRGF0YVxyXG4gICAgICAgICAgdGhpcy51cGRhdGVSZXN1bWFEYXRhKGlucHJvZ3Jlc3NEYXRhQ2hlY2spXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIC8vIGNvbnN0IHBhcmVudENvbnRlbnQgPSBlbnJvbG1lbnRMaXN0LmZpbmQoKGVsOiBhbnkpID0+IGVsLmNvbGxlY3Rpb25JZCA9PT0gY29udGVudC5pZGVudGlmaWVyKVxyXG4gICAgICAvLyBpZiAoIXBhcmVudENvbnRlbnQuY29tcGxldGlvblBlcmNlbnRhZ2UpIHtcclxuICAgICAgY29uc3QgY2FsY3VsYXRlZFBjdCA9IE1hdGguZmxvb3IoKHRvdGFsQ291bnQgLyBsZWFmbm9kZUNvdW50KSAqIDEwMClcclxuICAgICAgY29udGVudC5jb21wbGV0aW9uUGVyY2VudGFnZSA9IGlzTmFOKGNhbGN1bGF0ZWRQY3QpID8gMCA6IGNhbGN1bGF0ZWRQY3RcclxuICAgICAgY29udGVudC5jb21wbGV0aW9uU3RhdHVzID0gY29udGVudC5jb21wbGV0aW9uUGVyY2VudGFnZSA+PSAxMDAgPyAyIDogKGNvbnRlbnQuY29tcGxldGlvblBlcmNlbnRhZ2UgPiAwID8gMSA6IDApXHJcbiAgICAgIGlmIChjb250ZW50LmNvbXBsZXRpb25QZXJjZW50YWdlID09PSAxMDAgJiYgaW5wcm9ncmVzc0RhdGFDaGVjayAmJiBpbnByb2dyZXNzRGF0YUNoZWNrLmxlbmd0aCA9PT0gMCAmJiAhZmlyc3RVbmNvbXBsZXRlQ291cnNlKSB7XHJcbiAgICAgICAgY29uc3QgZmlyc3RDaGlsZERhdGEgPSB0aGlzLndpZGdldFN2Yy5nZXRGaXJzdENoaWxkSW5IaWVyYXJjaHkoY29udGVudClcclxuICAgICAgICBjb25zdCBjaGlsZEVucm9sbG1lbnREYXRhID0gZW5yb2xtZW50TGlzdC5maW5kKChlbDogYW55KSA9PlxyXG4gICAgICAgICAgZWwuY29sbGVjdGlvbklkID09PSBjb250ZW50LmNoaWxkcmVuWzBdLmlkZW50aWZpZXIpXHJcbiAgICAgICAgY29uc3QgcmVzdW1lRGF0YSA9IFt7XHJcbiAgICAgICAgICBjb250ZW50SWQ6IGZpcnN0Q2hpbGREYXRhLmlkZW50aWZpZXIsXHJcbiAgICAgICAgICBiYXRjaElkOiBjaGlsZEVucm9sbG1lbnREYXRhICYmIGNoaWxkRW5yb2xsbWVudERhdGEuYmF0Y2hJZCxcclxuICAgICAgICAgIGNvbXBsZXRlZENvdW50OiAxLFxyXG4gICAgICAgICAgY29tcGxldGlvblBlcmNlbnRhZ2U6IDEwMCxcclxuICAgICAgICAgIHByb2dyZXNzOiAyLFxyXG4gICAgICAgICAgdmlld0NvdW50OiAxLFxyXG4gICAgICAgICAgY291cnNlSWQ6IGNoaWxkRW5yb2xsbWVudERhdGEgJiYgY2hpbGRFbnJvbGxtZW50RGF0YS5jb3Vyc2VJZCxcclxuICAgICAgICAgIGNvbGxlY3Rpb25JZDogY2hpbGRFbnJvbGxtZW50RGF0YSAmJiBjaGlsZEVucm9sbG1lbnREYXRhLmNvdXJzZUlkLFxyXG4gICAgICAgICAgc3RhdHVzOiAyLFxyXG4gICAgICAgIH1dXHJcbiAgICAgICAgaW5wcm9ncmVzc0RhdGFDaGVjayA9IHJlc3VtZURhdGFcclxuICAgICAgICB0aGlzLnVwZGF0ZVJlc3VtYURhdGEoaW5wcm9ncmVzc0RhdGFDaGVjaylcclxuICAgICAgfVxyXG4gICAgICAvLyAvLyB9IGVsc2Uge1xyXG4gICAgICAvLyAgIGNvbnRlbnQuY29tcGxldGlvblBlcmNlbnRhZ2UgPSBwYXJlbnRDb250ZW50LmNvbXBsZXRpb25QZXJjZW50YWdlXHJcbiAgICAgIC8vIC8vIH1cclxuICAgICAgLy8gfSlcclxuICAgICAgLy8gdGhpcy5tYXBNb2R1bGVEdXJhdGlvbkFuZFByb2dyZXNzKGNvbnRlbnQsIGNvbnRlbnQpXHJcbiAgICAgIHRoaXMuY2FsbEhpcmFyY2h5UHJvZ3Jlc3NIYXNobWFwKGNvbnRlbnQpXHJcbiAgICAgIHRoaXMuY2hlY2tNb2R1bGVXaXNlRGF0YShjb250ZW50KVxyXG4gICAgICAvLyBDb21wdXRlIG1pbGVzdG9uZSBsb2NraW5nIEFGVEVSIHByb2dyZXNzIGRhdGEgaXMgcG9wdWxhdGVkXHJcbiAgICAgIGlmIChjb250ZW50LmNvdXJzZUNhdGVnb3J5ID09PSAnTGVhcm5pbmcgUGF0aHdheScpIHtcclxuICAgICAgICB0aGlzLmNvbXB1dGVNaWxlc3RvbmVMb2NraW5nU3RhdHVzKClcclxuICAgICAgICAvLyBFbnN1cmUgaGFzaG1hcCB1cGRhdGVzIGFyZSBwdWJsaXNoZWQgZm9yIGNoYW5nZSBkZXRlY3Rpb25cclxuICAgICAgICB0aGlzLmhhc2htYXAgPSB7IC4uLnRoaXMuaGFzaG1hcCB9XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5jb250ZW50TG9hZGVyLm5leHQoZmFsc2UpXHJcbiAgICB9XHJcbiAgfVxyXG4gIGNoZWNrQ29tcGxldGVkTGVhZm5vZGVzKGxlYWZOb2RlczogYW55LCBjb21wbGV0ZWRDb3VudDogYW55KSB7XHJcbiAgICBpZiAoY29tcGxldGVkQ291bnQubGVuZ3RoID4gMCkge1xyXG4gICAgICBjb21wbGV0ZWRDb3VudC5mb3JFYWNoKChlbGU6IGFueSkgPT4ge1xyXG4gICAgICAgIGlmICghbGVhZk5vZGVzLmluY2x1ZGVzKGVsZS5jb250ZW50SWQpKSB7XHJcbiAgICAgICAgICBsZWFmTm9kZXMucHVzaChlbGUuY29udGVudElkKVxyXG4gICAgICAgIH1cclxuICAgICAgfSlcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIGFzeW5jIGdldFByb2dyZXNzRm9yQ2hpbGRDb3Vyc2UocmVxdWVzdDogYW55LCBjb250ZW50OiBhbnkpIHtcclxuICAvLyAgY29uc3QgZGF0YTogYW55ID0gICBhd2FpdCB0aGlzLmZldGNoQ29udGVudEhpc3RvcnlWMihyZXF1ZXN0KS50b1Byb21pc2UoKS5jYXRjaChfZXJyb3IgPT4ge30pXHJcbiAgLy8gICBpZiAoZGF0YS5yZXN1bHQgJiYgZGF0YS5yZXN1bHQuY29udGVudExpc3QubGVuZ3RoID4gMCkge1xyXG4gIC8vICAgICB0aGlzLm1hcENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQsIGRhdGEucmVzdWx0LmNvbnRlbnRMaXN0KVxyXG4gIC8vIH1cclxuICAvLyB9XHJcblxyXG4gIGZpbmRFbnJvbG1lbnRCeUNvbGxlY3Rpb25JZChlbnJvbG1lbnRMaXN0OiBhbnksIGlkZW50aWZpZXI6IHN0cmluZykge1xyXG4gICAgcmV0dXJuIGVucm9sbWVudExpc3QgJiYgZW5yb2xtZW50TGlzdD8ubGVuZ3RoICYmIGVucm9sbWVudExpc3QuZmluZCgoZWw6IGFueSkgPT4gZWw/LmNvbGxlY3Rpb25JZCA9PT0gaWRlbnRpZmllcilcclxuICB9XHJcblxyXG4gIGFzeW5jIG1hcENvbXBsZXRpb25DaGlsZFBlcmNlbnRhZ2VQcm9ncmFtKGNvdXJzZTogYW55KSB7XHJcbiAgICBpZiAoY291cnNlICYmIGNvdXJzZS5jaGlsZHJlbikge1xyXG4gICAgICBhd2FpdCBjb3Vyc2UuY2hpbGRyZW4ubWFwKGFzeW5jIChjb3Vyc2VDaGlsZDogYW55KSA9PiB7XHJcbiAgICAgICAgaWYgKChjb3Vyc2VDaGlsZCAmJiBjb3Vyc2VDaGlsZC5jaGlsZHJlbikgfHwgY291cnNlQ2hpbGQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5NT0RVTEUpIHtcclxuICAgICAgICAgIHRoaXMubWFwQ29tcGxldGlvbkNoaWxkUGVyY2VudGFnZVByb2dyYW0oY291cnNlQ2hpbGQpXHJcbiAgICAgICAgICBjb3Vyc2VbJ21vZHVsZUNvdW50J10gPSBjb3Vyc2VbJ21vZHVsZUNvdW50J10gPyBjb3Vyc2VbJ21vZHVsZUNvdW50J10gKyAxIDogMVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBjb3Vyc2VDaGlsZFsnY29tcGxldGlvblBlcmNlbnRhZ2UnXSA9IDEwMFxyXG4gICAgICAgICAgY291cnNlQ2hpbGRbJ2NvbXBsZXRpb25TdGF0dXMnXSA9IDJcclxuICAgICAgICB9XHJcbiAgICAgIH0pXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbWFwTW9kdWxlRHVyYXRpb25BbmRQcm9ncmVzcyhjb250ZW50OiBOc0NvbnRlbnQuSUNvbnRlbnQgfCBudWxsLCBwYXJlbnQ6IE5zQ29udGVudC5JQ29udGVudCB8IG51bGwpIHtcclxuICAgIGlmIChjb250ZW50ICYmIGNvbnRlbnQuY2hpbGRyZW4pIHtcclxuICAgICAgaWYgKGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5NT0RVTEUpIHtcclxuICAgICAgICAvLyBjb250ZW50LmNoaWxkcmVuLm1hcCgoaXRlbTogTnNDb250ZW50LklDb250ZW50KT0+IHtcclxuICAgICAgICAvKiB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmUgKi9cclxuICAgICAgICBjb250ZW50ID0gdGhpcy5nZXRDYWxjdWxhdGlvbnNGcm9tQ2hpbGRyZW4oY29udGVudClcclxuICAgICAgICAvLyB9KVxyXG4gICAgICB9XHJcblxyXG4gICAgICBjb250ZW50LmNoaWxkcmVuLm1hcCgoaXRlbTogTnNDb250ZW50LklDb250ZW50KSA9PiB7XHJcbiAgICAgICAgLy8gaWYgKGl0ZW0ucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5NT0RVTEUpIHtcclxuICAgICAgICAvLyAgIHRoaXMubWFwTW9kdWxlRHVyYXRpb25BbmRQcm9ncmVzcyhpdGVtLCBwYXJlbnQpXHJcbiAgICAgICAgLy8gfSBlbHNlIHtcclxuICAgICAgICAvLyAgIHRoaXMubWFwTW9kdWxlRHVyYXRpb25BbmRQcm9ncmVzcyhpdGVtLCBwYXJlbnQpXHJcbiAgICAgICAgLy8gfVxyXG4gICAgICAgIGlmIChpdGVtICYmIGl0ZW0uY2hpbGRyZW4pIHtcclxuICAgICAgICAgIHRoaXMubWFwTW9kdWxlRHVyYXRpb25BbmRQcm9ncmVzcyhpdGVtLCBwYXJlbnQpXHJcbiAgICAgICAgfVxyXG4gICAgICB9KVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHVibGljIGNyZWF0ZUhpcmFyY2h5UHJvZ3Jlc3NIYXNobWFwKGhpZXJhcmNoeURhdGE6IE5zQ29udGVudC5JQ29udGVudCwgcm9vdENvdXJzZUNhdGVnb3J5Pzogc3RyaW5nKSB7XHJcbiAgICBpZiAoaGllcmFyY2h5RGF0YSAmJiBoaWVyYXJjaHlEYXRhLmNoaWxkcmVuKSB7XHJcbiAgICAgIGhpZXJhcmNoeURhdGEuY2hpbGRyZW4uZm9yRWFjaCgoY2hpbGQ6IE5zQ29udGVudC5JQ29udGVudCkgPT4ge1xyXG4gICAgICAgIGlmIChjaGlsZCAmJiBjaGlsZC5jaGlsZHJlbikge1xyXG4gICAgICAgICAgdGhpcy5jcmVhdGVIaXJhcmNoeVByb2dyZXNzSGFzaG1hcChjaGlsZCwgcm9vdENvdXJzZUNhdGVnb3J5KVxyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBwcmltYXJ5Q2F0ID0gY2hpbGQucHJpbWFyeUNhdGVnb3J5IGFzIHN0cmluZ1xyXG4gICAgICAgIGNvbnN0IGNvdXJzZUNhdCA9IChjaGlsZC5jb3Vyc2VDYXRlZ29yeSB8fCBjaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgfHwgJycpIGFzIHN0cmluZ1xyXG4gICAgICAgIGNvbnN0IGlzTWlsZXN0b25lID0gcHJpbWFyeUNhdCA9PT0gJ01pbGVzdG9uZScgfHwgY291cnNlQ2F0ID09PSAnTWlsZXN0b25lJ1xyXG4gICAgICAgIGNvbnN0IGlzQ29sbGVjdGlvbiA9IGNoaWxkLm1pbWVUeXBlID09PSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5DT0xMRUNUSU9OXHJcbiAgICAgICAgY29uc3QgaXNNb2R1bGUgPSBjaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk1PRFVMRVxyXG4gICAgICAgIGNvbnN0IGlzUmVzb3VyY2UgPSBjaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LlJFU09VUkNFIHx8XHJcbiAgICAgICAgICBjaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFIHx8XHJcbiAgICAgICAgICBjaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgfHxcclxuICAgICAgICAgIGNoaWxkLnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuQ09NUF9BU1NFU1NNRU5UXHJcbiAgICAgICAgY29uc3QgaXNMZWFybmluZ1BhdGh3YXkgPSByb290Q291cnNlQ2F0ZWdvcnkgPT09ICdMZWFybmluZyBQYXRod2F5J1xyXG5cclxuICAgICAgICAvLyBDaGVjayBpZiBjb250ZW50IGlzIG1hbmRhdG9yeSAoaXNNYW5kYXRvcnkgZmxhZyBvciBtYW5kYXRvcnkgcHJvcGVydHkpXHJcbiAgICAgICAgY29uc3QgaXNNYW5kYXRvcnkgPSBjaGlsZC5pc01hbmRhdG9yeSA9PT0gdHJ1ZSB8fCAoY2hpbGQgYXMgYW55KS5tYW5kYXRvcnkgPT09IHRydWVcclxuXHJcbiAgICAgICAgbGV0IGxvY2FsTWFwOiBhbnkgPSB7XHJcbiAgICAgICAgICBwYXJlbnQ6IGNoaWxkPy5wYXJlbnQsXHJcbiAgICAgICAgICBpZGVudGlmaWVyOiBjaGlsZC5pZGVudGlmaWVyLFxyXG4gICAgICAgICAgbGVhZk5vZGVzQ291bnQ6IGNoaWxkLmxlYWZOb2Rlc0NvdW50IHx8IG51bGwsXHJcbiAgICAgICAgICBsZWFmTm9kZXM6IGNoaWxkLmxlYWZOb2RlcyB8fCBbXSxcclxuICAgICAgICAgIGNvbXBsZXRpb25QZXJjZW50YWdlOiBjaGlsZC5jb21wbGV0aW9uUGVyY2VudGFnZSB8fCBjaGlsZC5wcm9ncmVzcyB8fCAwLFxyXG4gICAgICAgICAgY29tcGxldGlvblN0YXR1czogY2hpbGQuY29tcGxldGlvblN0YXR1cyB8fCBjaGlsZC5zdGF0dXMgfHwgMCxcclxuICAgICAgICAgIHN0YXR1czogY2hpbGQuc3RhdHVzIHx8IGNoaWxkLmNvbXBsZXRpb25TdGF0dXMgfHwgMCxcclxuICAgICAgICAgIHByb2dyZXNzOiBjaGlsZC5wcm9ncmVzcyxcclxuICAgICAgICAgIHByaW1hcnlDYXRlZ29yeTogY2hpbGQucHJpbWFyeUNhdGVnb3J5LFxyXG4gICAgICAgICAgY291cnNlQ2F0ZWdvcnk6IGNvdXJzZUNhdCxcclxuICAgICAgICAgIGR1cmF0aW9uOiBjaGlsZC5kdXJhdGlvbiB8fCAwLFxyXG4gICAgICAgICAgZXhwZWN0ZWREdXJhdGlvbjogY2hpbGQuZXhwZWN0ZWREdXJhdGlvbiB8fCAwLFxyXG4gICAgICAgICAgLy8gQWRkaXRpb25hbCBtZXRhZGF0YSBmb3IgcGVyZm9ybWFuY2Ugb3B0aW1pemF0aW9uXHJcbiAgICAgICAgICBtaW1lVHlwZTogY2hpbGQubWltZVR5cGUsXHJcbiAgICAgICAgICBpc0xvY2tlZDogY2hpbGQuaXNMb2NrZWQgfHwgZmFsc2UsXHJcbiAgICAgICAgICBhcnRpZmFjdFVybDogY2hpbGQuYXJ0aWZhY3RVcmwgfHwgbnVsbCxcclxuICAgICAgICAgIG5hbWU6IGNoaWxkLm5hbWUgfHwgJycsXHJcbiAgICAgICAgICBjb250ZW50VHlwZTogY2hpbGQuY29udGVudFR5cGUgfHwgJycsXHJcbiAgICAgICAgICAvLyBQcmUtY29tcHV0ZWQgZmxhZ3MgZm9yIExlYXJuaW5nIFBhdGh3YXlcclxuICAgICAgICAgIGlzTWlsZXN0b25lOiBpc01pbGVzdG9uZSxcclxuICAgICAgICAgIGlzQ29sbGVjdGlvbjogaXNDb2xsZWN0aW9uLFxyXG4gICAgICAgICAgaXNNb2R1bGU6IGlzTW9kdWxlLFxyXG4gICAgICAgICAgaXNSZXNvdXJjZTogaXNSZXNvdXJjZSxcclxuICAgICAgICAgIGlzTGVhcm5pbmdQYXRod2F5OiBpc0xlYXJuaW5nUGF0aHdheSxcclxuICAgICAgICAgIGlzTWFuZGF0b3J5OiBpc01hbmRhdG9yeSxcclxuICAgICAgICAgIC8vIE1pbGVzdG9uZSBzcGVjaWZpYyBkYXRhXHJcbiAgICAgICAgICBtaWxlc3RvbmVJbmRleDogKGNoaWxkIGFzIGFueSkubWlsZXN0b25lSW5kZXgsXHJcbiAgICAgICAgICBjb21wbGV0ZWRMZWFmTm9kZXNDb3VudDogKGNoaWxkIGFzIGFueSkuY29tcGxldGVkTGVhZk5vZGVzQ291bnQgfHwgMCxcclxuICAgICAgICAgIC8vIFByZS1hc3Nlc3NtZW50IGZsYWcgKGZvciBtaWxlc3RvbmUgZ2F0aW5nKVxyXG4gICAgICAgICAgaXNQcmVBc3Nlc3NtZW50OiAoY2hpbGQgYXMgYW55KS5pc1ByZUFzc2Vzc21lbnQgfHwgZmFsc2UsXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBEZWJ1ZyBsb2dnaW5nIGZvciBtaWxlc3RvbmVzXHJcbiAgICAgICAgaWYgKGlzTWlsZXN0b25lKSB7XHJcbiAgICAgICAgICAvLyBQcm9ncmVzcyB0cmFja2VkIGZvciBtaWxlc3RvbmVcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuaGFzaG1hcFtjaGlsZC5pZGVudGlmaWVyXSA9IGxvY2FsTWFwXHJcbiAgICAgIH0pXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgY3JlYXRlUHJlQXNzZXNzbWVudEhpcmFyY2h5UHJvZ3Jlc3NIYXNobWFwKGhpZXJhcmNoeURhdGE6IE5zQ29udGVudC5JQ29udGVudCkge1xyXG4gICAgaWYgKGhpZXJhcmNoeURhdGEgJiYgaGllcmFyY2h5RGF0YS5wcmVFbnJvbG1lbnRSZXNvdXJjZXMpIHtcclxuICAgICAgaGllcmFyY2h5RGF0YS5wcmVFbnJvbG1lbnRSZXNvdXJjZXMuZm9yRWFjaCgoY2hpbGQ6IE5zQ29udGVudC5JQ29udGVudCkgPT4ge1xyXG4gICAgICAgIGlmIChjaGlsZCAmJiBjaGlsZC5wcmVFbnJvbG1lbnRSZXNvdXJjZXMpIHtcclxuICAgICAgICAgIHRoaXMuY3JlYXRlUHJlQXNzZXNzbWVudEhpcmFyY2h5UHJvZ3Jlc3NIYXNobWFwKGNoaWxkKVxyXG4gICAgICAgIH1cclxuICAgICAgICBsZXQgbG9jYWxNYXAgPSB7fVxyXG4gICAgICAgIGxvY2FsTWFwID0ge1xyXG4gICAgICAgICAgcGFyZW50OiBjaGlsZD8ucGFyZW50LFxyXG4gICAgICAgICAgaWRlbnRpZmllcjogY2hpbGQuaWRlbnRpZmllcixcclxuICAgICAgICAgIGxlYWZOb2Rlc0NvdW50OiBjaGlsZC5sZWFmTm9kZXNDb3VudCB8fCBudWxsLFxyXG4gICAgICAgICAgbGVhZk5vZGVzOiBjaGlsZC5sZWFmTm9kZXMgfHwgW10sXHJcbiAgICAgICAgICBjb21wbGV0aW9uUGVyY2VudGFnZTogY2hpbGQuY29tcGxldGlvblBlcmNlbnRhZ2UgfHwgY2hpbGQucHJvZ3Jlc3MsXHJcbiAgICAgICAgICBjb21wbGV0aW9uU3RhdHVzOiBjaGlsZC5jb21wbGV0aW9uU3RhdHVzLFxyXG4gICAgICAgICAgc3RhdHVzOiBjaGlsZC5zdGF0dXMgfHwgY2hpbGQuY29tcGxldGlvblN0YXR1cyB8fCAwLFxyXG4gICAgICAgICAgcHJvZ3Jlc3M6IGNoaWxkLnByb2dyZXNzLFxyXG4gICAgICAgICAgcHJpbWFyeUNhdGVnb3J5OiBjaGlsZC5wcmltYXJ5Q2F0ZWdvcnksXHJcbiAgICAgICAgICBjb3Vyc2VDYXRlZ29yeTogY2hpbGQuY291cnNlQ2F0ZWdvcnkgfHwgY2hpbGQucHJpbWFyeUNhdGVnb3J5IHx8ICcnLFxyXG4gICAgICAgICAgZHVyYXRpb246IGNoaWxkLmR1cmF0aW9uIHx8IDAsXHJcbiAgICAgICAgICBleHBlY3RlZER1cmF0aW9uOiBjaGlsZC5leHBlY3RlZER1cmF0aW9uIHx8IDAsXHJcbiAgICAgICAgICAvLyBNYXJrIGFzIHByZS1hc3Nlc3NtZW50IE9OTFkgaWYgZXhwbGljaXRseSBzZXQgLSBkbyBOT1QgZGVmYXVsdCB0byB0cnVlXHJcbiAgICAgICAgICBpc1ByZUFzc2Vzc21lbnQ6IGNoaWxkLmlzUHJlQXNzZXNzbWVudCB8fCBmYWxzZSxcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5oYXNobWFwW2NoaWxkLmlkZW50aWZpZXJdID0gbG9jYWxNYXBcclxuICAgICAgfSlcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHB1YmxpYyBjYWxsSGlyYXJjaHlQcm9ncmVzc0hhc2htYXAoaGllcmFyY2h5RGF0YTogTnNDb250ZW50LklDb250ZW50IHwgbnVsbCkge1xyXG4gICAgaWYgKGhpZXJhcmNoeURhdGEpIHtcclxuICAgICAgY29uc3Qgcm9vdENvdXJzZUNhdGVnb3J5ID0gaGllcmFyY2h5RGF0YS5jb3Vyc2VDYXRlZ29yeSB8fCBoaWVyYXJjaHlEYXRhLnByaW1hcnlDYXRlZ29yeSB8fCAnJ1xyXG4gICAgICBjb25zdCBpc0xlYXJuaW5nUGF0aHdheSA9IHJvb3RDb3Vyc2VDYXRlZ29yeSA9PT0gJ0xlYXJuaW5nIFBhdGh3YXknXHJcblxyXG4gICAgICB0aGlzLmhhc2htYXBbaGllcmFyY2h5RGF0YS5pZGVudGlmaWVyXSA9IHtcclxuICAgICAgICBwYXJlbnQ6IGhpZXJhcmNoeURhdGEucGFyZW50LFxyXG4gICAgICAgIGlkZW50aWZpZXI6IGhpZXJhcmNoeURhdGEuaWRlbnRpZmllcixcclxuICAgICAgICBsZWFmTm9kZXNDb3VudDogaGllcmFyY2h5RGF0YS5sZWFmTm9kZXNDb3VudCB8fCBudWxsLFxyXG4gICAgICAgIGxlYWZOb2RlczogaGllcmFyY2h5RGF0YS5sZWFmTm9kZXMgfHwgW10sXHJcbiAgICAgICAgY29tcGxldGlvblBlcmNlbnRhZ2U6IGhpZXJhcmNoeURhdGEuY29tcGxldGlvblBlcmNlbnRhZ2UgfHwgaGllcmFyY2h5RGF0YS5wcm9ncmVzcyB8fCAwLFxyXG4gICAgICAgIGNvbXBsZXRpb25TdGF0dXM6IGhpZXJhcmNoeURhdGEuY29tcGxldGlvblN0YXR1cyB8fCAwLFxyXG4gICAgICAgIHByb2dyZXNzOiBoaWVyYXJjaHlEYXRhLnByb2dyZXNzLFxyXG4gICAgICAgIHByaW1hcnlDYXRlZ29yeTogaGllcmFyY2h5RGF0YS5wcmltYXJ5Q2F0ZWdvcnksXHJcbiAgICAgICAgY291cnNlQ2F0ZWdvcnk6IHJvb3RDb3Vyc2VDYXRlZ29yeSxcclxuICAgICAgICBleHBlY3RlZER1cmF0aW9uOiBoaWVyYXJjaHlEYXRhLmV4cGVjdGVkRHVyYXRpb24gfHwgMCxcclxuICAgICAgICAvLyBBZGRpdGlvbmFsIG1ldGFkYXRhXHJcbiAgICAgICAgbWltZVR5cGU6IGhpZXJhcmNoeURhdGEubWltZVR5cGUsXHJcbiAgICAgICAgaXNMb2NrZWQ6IGhpZXJhcmNoeURhdGEuaXNMb2NrZWQgfHwgZmFsc2UsXHJcbiAgICAgICAgYXJ0aWZhY3RVcmw6IGhpZXJhcmNoeURhdGEuYXJ0aWZhY3RVcmwgfHwgbnVsbCxcclxuICAgICAgICBuYW1lOiBoaWVyYXJjaHlEYXRhLm5hbWUgfHwgJycsXHJcbiAgICAgICAgY29udGVudFR5cGU6IGhpZXJhcmNoeURhdGEuY29udGVudFR5cGUgfHwgJycsXHJcbiAgICAgICAgaXNNaWxlc3RvbmU6IGZhbHNlLFxyXG4gICAgICAgIGlzQ29sbGVjdGlvbjogaGllcmFyY2h5RGF0YS5taW1lVHlwZSA9PT0gTnNDb250ZW50LkVNaW1lVHlwZXMuQ09MTEVDVElPTixcclxuICAgICAgICBpc01vZHVsZTogaGllcmFyY2h5RGF0YS5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk1PRFVMRSxcclxuICAgICAgICBpc1Jlc291cmNlOiBmYWxzZSxcclxuICAgICAgICBpc0xlYXJuaW5nUGF0aHdheTogaXNMZWFybmluZ1BhdGh3YXksXHJcbiAgICAgIH1cclxuICAgICAgaWYgKGhpZXJhcmNoeURhdGEucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5DVVJBVEVEX1BST0dSQU0gJiZcclxuICAgICAgICBoaWVyYXJjaHlEYXRhLmNvbXBhdGliaWxpdHlMZXZlbCA+PSA1ICYmIGhpZXJhcmNoeURhdGEuY29udGV4dExvY2tpbmdUeXBlICYmXHJcbiAgICAgICAgaGllcmFyY2h5RGF0YS5jb250ZXh0TG9ja2luZ1R5cGUgPT09IE5zQ29udGVudC5FQ29udGV4dExvY2tpbmdUeXBlLkNPVVJTRV9BU1NFU1NNRU5UX09OTFkpIHtcclxuICAgICAgICB0aGlzLmhhc2htYXBbaGllcmFyY2h5RGF0YS5pZGVudGlmaWVyXSA9IHtcclxuICAgICAgICAgIC4uLnRoaXMuaGFzaG1hcFtoaWVyYXJjaHlEYXRhLmlkZW50aWZpZXJdLFxyXG4gICAgICAgICAgY29udGV4dExvY2tpbmdUeXBlOiBoaWVyYXJjaHlEYXRhLmNvbnRleHRMb2NraW5nVHlwZSxcclxuICAgICAgICAgIGNvbXBhdGliaWxpdHlMZXZlbDogaGllcmFyY2h5RGF0YS5jb21wYXRpYmlsaXR5TGV2ZWwsXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuY3JlYXRlSGlyYXJjaHlQcm9ncmVzc0hhc2htYXAoaGllcmFyY2h5RGF0YSwgcm9vdENvdXJzZUNhdGVnb3J5KVxyXG4gICAgICAvLyBOT1RFOiBjb21wdXRlTWlsZXN0b25lTG9ja2luZ1N0YXR1cyBpcyBjYWxsZWQgQUZURVIgcHJvZ3Jlc3MgZGF0YSBpcyBwb3B1bGF0ZWRcclxuICAgICAgLy8gaW4gbWFwQ29tcGxldGlvblBlcmNlbnRhZ2VQcm9ncmFtLCBub3QgaGVyZSB3aGVyZSBjb21wbGV0aW9uIGRhdGEgaXMgc3RpbGwgMFxyXG4gICAgICB0aGlzLmhhc2htYXAgPSB7IC4uLnRoaXMuaGFzaG1hcCB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBQcmUtY29tcHV0ZSBtaWxlc3RvbmUgbG9ja2luZyBzdGF0dXMgZm9yIGFsbCBtaWxlc3RvbmVzIGluIExlYXJuaW5nIFBhdGh3YXlcclxuICAgKiBUaGlzIGF2b2lkcyBleHBlbnNpdmUgY2FsY3VsYXRpb25zIGluIGNvbXBvbmVudCBnZXR0ZXJzXHJcbiAgICogXHJcbiAgICogTG9ja2luZyBSdWxlczpcclxuICAgKiAwLiBJZiB1c2VyIGlzIG5vdCBlbnJvbGxlZCwgQUxMIG1pbGVzdG9uZXMgYXJlIGxvY2tlZFxyXG4gICAqIDEuIEFsbCBtaWxlc3RvbmVzIGFyZSBsb2NrZWQgYnkgZGVmYXVsdFxyXG4gICAqIDIuIE1pbGVzdG9uZSAxIChNMSkgdW5sb2NrcyB3aGVuIHByZS1hc3Nlc3NtZW50IGlzIGNvbXBsZXRlZFxyXG4gICAqIDMuIE1pbGVzdG9uZSBOIChOID4gMSkgdW5sb2NrcyB3aGVuOlxyXG4gICAqICAgIC0gQWxsIG1hbmRhdG9yeSBsZWFybmluZyBpdGVtcyBpbiBNaWxlc3RvbmUgTi0xIGFyZSBjb21wbGV0ZWRcclxuICAgKiAgICAtIFRoZSBhc3Nlc3NtZW50IG9mIE1pbGVzdG9uZSBOLTEgaXMgY29tcGxldGVkXHJcbiAgICovXHJcbiAgLyoqXHJcbiAgICog4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQXHJcbiAgICogTEVBUk5JTkcgUEFUSFdBWSBNSUxFU1RPTkUgTE9DS0lORyBTWVNURU0gLSBTSU5HTEUgU09VUkNFIE9GIFRSVVRIXHJcbiAgICog4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQXHJcbiAgICogXHJcbiAgICogVGhpcyBtZXRob2QgaXMgdGhlIFNJTkdMRSBTT1VSQ0UgT0YgVFJVVEggZm9yIGFsbCBtaWxlc3RvbmUgYW5kIGFzc2Vzc21lbnQgbG9ja2luZy5cclxuICAgKiBBbGwgbG9ja2luZyBsb2dpYyBpcyBjb21wdXRlZCBoZXJlIGFuZCBzdG9yZWQgaW4gdGhlIGhhc2htYXAuXHJcbiAgICogQ29tcG9uZW50cyBSRUFEIE9OTFkgZnJvbSB0aGUgaGFzaG1hcCAtIHRoZXkgZG8gTk9UIGNvbXB1dGUgbG9ja3MgdGhlbXNlbHZlcy5cclxuICAgKiBcclxuICAgKiBMT0NLSU5HIFJVTEVTOlxyXG4gICAqIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxyXG4gICAqIDEuIERFRkFVTFQgU1RBVEU6IEFsbCBtaWxlc3RvbmVzIGFyZSBMT0NLRUQgYnkgZGVmYXVsdFxyXG4gICAqIFxyXG4gICAqIDIuIE1JTEVTVE9ORSAxIFVOTE9DS0lORzpcclxuICAgKiAgICAtIFVubG9ja3Mgd2hlbjogUHJlLWFzc2Vzc21lbnQgaXMgMTAwJSBjb21wbGV0ZVxyXG4gICAqICAgIC0gTG9jayBtZXNzYWdlOiBcIkNvbXBsZXRlIHRoZSBwcmVsaW1pbmFyeSBhc3Nlc3NtZW50IHRvIHVubG9jayB0aGlzIG1pbGVzdG9uZVwiXHJcbiAgICogXHJcbiAgICogMy4gTUlMRVNUT05FIE4gKE4gPj0gMikgVU5MT0NLSU5HOlxyXG4gICAqICAgIC0gVW5sb2NrcyB3aGVuOiBQcmV2aW91cyBtaWxlc3RvbmUgaXMgMTAwJSBjb21wbGV0ZVxyXG4gICAqICAgIC0gUHJldmlvdXMgbWlsZXN0b25lIGlzIGNvbXBsZXRlIHdoZW46XHJcbiAgICogICAgICBhKSBBbGwgTUFOREFUT1JZIGNvdXJzZXMgYXJlIDEwMCUgY29tcGxldGVcclxuICAgKiAgICAgIGIpIE1pbGVzdG9uZSBhc3Nlc3NtZW50IGlzIDEwMCUgY29tcGxldGVcclxuICAgKiAgICAtIExvY2sgbWVzc2FnZTogXCJDb21wbGV0ZSBhbGwgbWFuZGF0b3J5IGNvbnRlbnQgYW5kIGFzc2Vzc21lbnQgaW4gTWlsZXN0b25lIE4tMVwiXHJcbiAgICogXHJcbiAgICogNC4gQVNTRVNTTUVOVCBMT0NLSU5HICh3aXRoaW4gdW5sb2NrZWQgbWlsZXN0b25lcyk6XHJcbiAgICogICAgLSBBc3Nlc3NtZW50IGxvY2tlZCB1bnRpbDogQWxsIE1BTkRBVE9SWSBjb3Vyc2VzIGluIFNBTUUgbWlsZXN0b25lIGNvbXBsZXRlXHJcbiAgICogICAgLSBPcHRpb25hbCBjb3Vyc2VzIGRvIE5PVCBhZmZlY3QgYXNzZXNzbWVudCBsb2NraW5nXHJcbiAgICogICAgLSBBc3Nlc3NtZW50IGxvY2sgbWVzc2FnZTogXCJDb21wbGV0ZSBhbGwgbWFuZGF0b3J5IGl0ZW1zIHRvIHVubG9jayB0aGUgYXNzZXNzbWVudFwiXHJcbiAgICogICAgLSBPbmNlIGFzc2Vzc21lbnQgaXMgY29tcGxldGVkLCBpdCBzdGF5cyB1bmxvY2tlZFxyXG4gICAqIFxyXG4gICAqIDUuIFBBUkVOVCBNSUxFU1RPTkUgTE9DS0lORzpcclxuICAgKiAgICAtIEFsbCBjb250ZW50IGluc2lkZSBsb2NrZWQgbWlsZXN0b25lIGdldHMgaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQgPSB0cnVlXHJcbiAgICogICAgLSBUaGlzIGluY2x1ZGVzIGNvdXJzZXMsIGFzc2Vzc21lbnRzLCBuZXN0ZWQgcmVzb3VyY2VzXHJcbiAgICogXHJcbiAgICogNi4gTUFOREFUT1JZIHZzIE9QVElPTkFMOlxyXG4gICAqICAgIC0gQnkgZGVmYXVsdCwgQUxMIGNvdXJzZXMgYXJlIG1hbmRhdG9yeSAodW5sZXNzIGlzTWFuZGF0b3J5OiBmYWxzZSlcclxuICAgKiAgICAtIE9wdGlvbmFsIGNvdXJzZXMgZG8gTk9UIGJsb2NrIHByb2dyZXNzaW9uXHJcbiAgICogXHJcbiAgICog4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQXHJcbiAgICovXHJcbiAgcHVibGljIGNvbXB1dGVNaWxlc3RvbmVMb2NraW5nU3RhdHVzKGlzRW5yb2xsZWQ6IGJvb2xlYW4gPSB0cnVlKSB7XHJcbiAgICBpZiAoIXRoaXMuaGFzaG1hcCB8fCBPYmplY3Qua2V5cyh0aGlzLmhhc2htYXApLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICBjb25zb2xlLndhcm4oJ+KaoO+4jyAgSGFzaG1hcCBpcyBlbXB0eSAtIGNhbm5vdCBjb21wdXRlIG1pbGVzdG9uZSBsb2NraW5nJylcclxuICAgICAgcmV0dXJuXHJcbiAgICB9XHJcbiAgICBcclxuICAgIGNvbnNvbGUubG9nKCdcXG7ilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZAnKVxyXG4gICAgY29uc29sZS5sb2coJ/CflJIgTUlMRVNUT05FIExPQ0tJTkcgQ09NUFVUQVRJT04gU1RBUlQnKVxyXG4gICAgY29uc29sZS5sb2coJ+KVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkCcpXHJcbiAgICBjb25zb2xlLmxvZygnVXNlciBlbnJvbGxlZDonLCBpc0Vucm9sbGVkKVxyXG4gICAgY29uc29sZS5sb2coJ0hhc2htYXAgc2l6ZTonLCBPYmplY3Qua2V5cyh0aGlzLmhhc2htYXApLmxlbmd0aClcclxuICAgIFxyXG4gICAgLy8gU1RFUCAxOiBGaW5kIGFsbCBtaWxlc3RvbmVzIGFuZCBzb3J0IGJ5IGluZGV4XHJcbiAgICBjb25zdCBtaWxlc3RvbmVFbnRyaWVzID0gT2JqZWN0LmtleXModGhpcy5oYXNobWFwKVxyXG4gICAgICAuZmlsdGVyKGtleSA9PiB7XHJcbiAgICAgICAgY29uc3QgaXRlbSA9IHRoaXMuaGFzaG1hcFtrZXldXHJcbiAgICAgICAgcmV0dXJuIGl0ZW0uaXNNaWxlc3RvbmUgfHwgaXRlbS5wcmltYXJ5Q2F0ZWdvcnkgPT09ICdNaWxlc3RvbmUnIHx8IGl0ZW0uY291cnNlQ2F0ZWdvcnkgPT09ICdNaWxlc3RvbmUnXHJcbiAgICAgIH0pXHJcbiAgICAgIC5zb3J0KChhLCBiKSA9PiB7XHJcbiAgICAgICAgY29uc3QgaXRlbUEgPSB0aGlzLmhhc2htYXBbYV1cclxuICAgICAgICBjb25zdCBpdGVtQiA9IHRoaXMuaGFzaG1hcFtiXVxyXG4gICAgICAgIGlmIChpdGVtQS5taWxlc3RvbmVJbmRleCAhPT0gdW5kZWZpbmVkICYmIGl0ZW1CLm1pbGVzdG9uZUluZGV4ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgIHJldHVybiBpdGVtQS5taWxlc3RvbmVJbmRleCAtIGl0ZW1CLm1pbGVzdG9uZUluZGV4XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IG51bUEgPSBwYXJzZUludChhLnJlcGxhY2UoL1xcRC9nLCAnJykpIHx8IDBcclxuICAgICAgICBjb25zdCBudW1CID0gcGFyc2VJbnQoYi5yZXBsYWNlKC9cXEQvZywgJycpKSB8fCAwXHJcbiAgICAgICAgcmV0dXJuIG51bUEgLSBudW1CXHJcbiAgICAgIH0pXHJcblxyXG4gICAgaWYgKG1pbGVzdG9uZUVudHJpZXMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgIGNvbnNvbGUubG9nKCfihLnvuI8gIE5vIG1pbGVzdG9uZXMgZm91bmQgLSBza2lwcGluZyBtaWxlc3RvbmUgbG9ja2luZycpXHJcbiAgICAgIGNvbnNvbGUubG9nKCfilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZBcXG4nKVxyXG4gICAgICByZXR1cm5cclxuICAgIH1cclxuICAgIFxyXG4gICAgY29uc29sZS5sb2coYFxcbvCfk40gRm91bmQgJHttaWxlc3RvbmVFbnRyaWVzLmxlbmd0aH0gbWlsZXN0b25lczpgKVxyXG4gICAgbWlsZXN0b25lRW50cmllcy5mb3JFYWNoKChpZCwgaSkgPT4ge1xyXG4gICAgICBjb25zb2xlLmxvZyhgICAgTSR7aSArIDF9OiAke3RoaXMuaGFzaG1hcFtpZF0ubmFtZSB8fCBpZH1gKVxyXG4gICAgfSlcclxuXHJcbiAgICAvLyBTVEVQIDI6IElmIHVzZXIgTk9UIGVucm9sbGVkLCBsb2NrIEFMTCBtaWxlc3RvbmVzIGFuZCBjaGlsZHJlblxyXG4gICAgaWYgKCFpc0Vucm9sbGVkKSB7XHJcbiAgICAgIGNvbnNvbGUubG9nKCdcXG7imqDvuI8gIFVzZXIgTk9UIGVucm9sbGVkIC0gbG9ja2luZyBBTEwgbWlsZXN0b25lcyBhbmQgY2hpbGRyZW4nKVxyXG4gICAgICBtaWxlc3RvbmVFbnRyaWVzLmZvckVhY2gobWlsZXN0b25lSWQgPT4ge1xyXG4gICAgICAgIHRoaXMuaGFzaG1hcFttaWxlc3RvbmVJZF0uY29tcHV0ZWRJc0xvY2tlZCA9IHRydWVcclxuICAgICAgICB0aGlzLmhhc2htYXBbbWlsZXN0b25lSWRdLnVubG9ja01lc3NhZ2UgPSAnRW5yb2xsIGluIHRoaXMgY291cnNlIHRvIGFjY2VzcyBtaWxlc3RvbmVzJ1xyXG4gICAgICB9KVxyXG4gICAgICAvLyBMb2NrIGFsbCBjaGlsZHJlblxyXG4gICAgICBPYmplY3Qua2V5cyh0aGlzLmhhc2htYXApLmZvckVhY2goa2V5ID0+IHtcclxuICAgICAgICBpZiAoIXRoaXMuaGFzaG1hcFtrZXldLmlzTWlsZXN0b25lKSB7XHJcbiAgICAgICAgICB0aGlzLmhhc2htYXBba2V5XS5pc1BhcmVudE1pbGVzdG9uZUxvY2tlZCA9IHRydWVcclxuICAgICAgICB9XHJcbiAgICAgIH0pXHJcbiAgICAgIHRoaXMuaGFzaG1hcCA9IHsgLi4udGhpcy5oYXNobWFwIH1cclxuICAgICAgdGhpcy5oYXNobWFwVXBkYXRlZC5uZXh0KHsgdGltZXN0YW1wOiBEYXRlLm5vdygpLCBoYXNobWFwOiB0aGlzLmhhc2htYXAgfSlcclxuICAgICAgY29uc29sZS5sb2coJ+KVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkFxcbicpXHJcbiAgICAgIHJldHVyblxyXG4gICAgfVxyXG5cclxuICAgIC8vIFNURVAgMzogQ2hlY2sgcHJlLWFzc2Vzc21lbnQgY29tcGxldGlvblxyXG4gICAgY29uc3QgaXNQcmVBc3Nlc3NtZW50Q29tcGxldGVkID0gdGhpcy5jaGVja1ByZUFzc2Vzc21lbnRDb21wbGV0aW9uKClcclxuICAgIGNvbnNvbGUubG9nKGBcXG7wn5OdIFByZS1hc3Nlc3NtZW50OiAke2lzUHJlQXNzZXNzbWVudENvbXBsZXRlZCA/ICfinIUgQ09NUExFVEUnIDogJ+KdjCBJTkNPTVBMRVRFJ31gKVxyXG5cclxuICAgIC8vIFNURVAgNDogQ29tcHV0ZSBsb2NraW5nIGZvciBlYWNoIG1pbGVzdG9uZVxyXG4gICAgY29uc29sZS5sb2coJ1xcbvCflJAgQ29tcHV0aW5nIG1pbGVzdG9uZSBsb2NrczonKVxyXG4gICAgY29uc29sZS5sb2coJ+KUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgCcpXHJcbiAgICBcclxuICAgIG1pbGVzdG9uZUVudHJpZXMuZm9yRWFjaCgobWlsZXN0b25lSWQsIGluZGV4KSA9PiB7XHJcbiAgICAgIGNvbnN0IG1pbGVzdG9uZSA9IHRoaXMuaGFzaG1hcFttaWxlc3RvbmVJZF1cclxuICAgICAgaWYgKCFtaWxlc3RvbmUpIHJldHVyblxyXG5cclxuICAgICAgY29uc3QgbWlsZXN0b25lTnVtID0gaW5kZXggKyAxXHJcbiAgICAgIGNvbnNvbGUubG9nKGBcXG7wn5OMIE1pbGVzdG9uZSAke21pbGVzdG9uZU51bX0gKCR7bWlsZXN0b25lLm5hbWUgfHwgbWlsZXN0b25lSWR9KTpgKVxyXG5cclxuICAgICAgLy8gTUlMRVNUT05FIDE6IFVubG9ja3Mgd2hlbiBwcmUtYXNzZXNzbWVudCBjb21wbGV0ZVxyXG4gICAgICBpZiAoaW5kZXggPT09IDApIHtcclxuICAgICAgICBjb25zdCBpc0xvY2tlZCA9ICFpc1ByZUFzc2Vzc21lbnRDb21wbGV0ZWRcclxuICAgICAgICB0aGlzLmhhc2htYXBbbWlsZXN0b25lSWRdLmNvbXB1dGVkSXNMb2NrZWQgPSBpc0xvY2tlZFxyXG4gICAgICAgIHRoaXMuaGFzaG1hcFttaWxlc3RvbmVJZF0udW5sb2NrTWVzc2FnZSA9IGlzTG9ja2VkID9cclxuICAgICAgICAgICdDb21wbGV0ZSB0aGUgcHJlbGltaW5hcnkgYXNzZXNzbWVudCB0byB1bmxvY2sgdGhpcyBtaWxlc3RvbmUnIDogJydcclxuICAgICAgICBcclxuICAgICAgICBjb25zb2xlLmxvZyhgICAgJHtpc0xvY2tlZCA/ICfwn5SSIExPQ0tFRCcgOiAn8J+UkyBVTkxPQ0tFRCd9YClcclxuICAgICAgICBjb25zb2xlLmxvZyhgICAgUmVhc29uOiBQcmUtYXNzZXNzbWVudCAke2lzUHJlQXNzZXNzbWVudENvbXBsZXRlZCA/ICdjb21wbGV0ZScgOiAnaW5jb21wbGV0ZSd9YClcclxuICAgICAgICBcclxuICAgICAgICAvLyBGb3IgdW5sb2NrZWQgTTEsIGNoZWNrIGFzc2Vzc21lbnQgbG9ja2luZ1xyXG4gICAgICAgIGlmICghaXNMb2NrZWQpIHtcclxuICAgICAgICAgIGNvbnNvbGUubG9nKGAgICDinJMgQ2hlY2tpbmcgYXNzZXNzbWVudCBsb2NrLi4uYClcclxuICAgICAgICAgIHRoaXMuY29tcHV0ZUFzc2Vzc21lbnRMb2NraW5nSW5NaWxlc3RvbmUobWlsZXN0b25lSWQpXHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGNvbnNvbGUubG9nKGAgICDiqK8gTWlsZXN0b25lIGxvY2tlZCAtIG1hcmtpbmcgYWxsIGNoaWxkcmVuIGFzIHBhcmVudC1sb2NrZWRgKVxyXG4gICAgICAgICAgdGhpcy5tYXJrTWlsZXN0b25lQ2hpbGRyZW5Bc1BhcmVudExvY2tlZChtaWxlc3RvbmVJZCwgdHJ1ZSlcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuXHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIE1JTEVTVE9ORSBOIChOID4gMSk6IFVubG9ja3Mgd2hlbiBwcmV2aW91cyBtaWxlc3RvbmUgY29tcGxldGVcclxuICAgICAgY29uc3QgcHJldmlvdXNNaWxlc3RvbmVJZCA9IG1pbGVzdG9uZUVudHJpZXNbaW5kZXggLSAxXVxyXG4gICAgICBjb25zdCBwcmV2aW91c01pbGVzdG9uZSA9IHRoaXMuaGFzaG1hcFtwcmV2aW91c01pbGVzdG9uZUlkXVxyXG5cclxuICAgICAgaWYgKHByZXZpb3VzTWlsZXN0b25lKSB7XHJcbiAgICAgICAgLy8gQ2hlY2sgY29tcGxldGlvbiB2aWEgbXVsdGlwbGUgc3RyYXRlZ2llc1xyXG4gICAgICAgIGNvbnN0IHByZXZDb21wbGV0aW9uUGN0ID0gTnVtYmVyKHByZXZpb3VzTWlsZXN0b25lLmNvbXBsZXRpb25QZXJjZW50YWdlKSB8fCAwXHJcbiAgICAgICAgY29uc3QgcHJldkNvbXBsZXRpb25TdGF0dXMgPSBOdW1iZXIocHJldmlvdXNNaWxlc3RvbmUuY29tcGxldGlvblN0YXR1cykgfHwgMFxyXG4gICAgICAgIGNvbnN0IHByZXZTdGF0dXMgPSBOdW1iZXIocHJldmlvdXNNaWxlc3RvbmUuc3RhdHVzKSB8fCAwXHJcbiAgICAgICAgY29uc3QgcHJldkNvbXBsZXRlZExlYWZOb2RlcyA9IE51bWJlcihwcmV2aW91c01pbGVzdG9uZS5jb21wbGV0ZWRMZWFmTm9kZXNDb3VudCkgfHwgMFxyXG4gICAgICAgIGNvbnN0IHByZXZMZWFmTm9kZXNDb3VudCA9IE51bWJlcihwcmV2aW91c01pbGVzdG9uZS5sZWFmTm9kZXNDb3VudCkgfHwgMFxyXG5cclxuICAgICAgICBsZXQgcHJldmlvdXNNaWxlc3RvbmVDb21wbGV0ZSA9XHJcbiAgICAgICAgICBwcmV2Q29tcGxldGlvblBjdCA+PSAxMDAgfHxcclxuICAgICAgICAgIHByZXZDb21wbGV0aW9uU3RhdHVzID09PSAyIHx8XHJcbiAgICAgICAgICBwcmV2U3RhdHVzID09PSAyIHx8XHJcbiAgICAgICAgICAocHJldkxlYWZOb2Rlc0NvdW50ID4gMCAmJiBwcmV2Q29tcGxldGVkTGVhZk5vZGVzID49IHByZXZMZWFmTm9kZXNDb3VudClcclxuXHJcbiAgICAgICAgLy8gRmFsbGJhY2s6IENoZWNrIGluZGl2aWR1YWwgaXRlbXNcclxuICAgICAgICBpZiAoIXByZXZpb3VzTWlsZXN0b25lQ29tcGxldGUpIHtcclxuICAgICAgICAgIGNvbnN0IGlzUHJldmlvdXNNaWxlc3RvbmVBc3Nlc3NtZW50Q29tcGxldGUgPSB0aGlzLmNoZWNrTWlsZXN0b25lQXNzZXNzbWVudENvbXBsZXRlKHByZXZpb3VzTWlsZXN0b25lSWQpXHJcbiAgICAgICAgICBjb25zdCBpc1ByZXZpb3VzTWlsZXN0b25lTWFuZGF0b3J5Q29tcGxldGUgPSB0aGlzLmNoZWNrTWlsZXN0b25lTWFuZGF0b3J5Q29udGVudENvbXBsZXRlKHByZXZpb3VzTWlsZXN0b25lSWQpXHJcbiAgICAgICAgICBwcmV2aW91c01pbGVzdG9uZUNvbXBsZXRlID0gaXNQcmV2aW91c01pbGVzdG9uZUFzc2Vzc21lbnRDb21wbGV0ZSAmJiBpc1ByZXZpb3VzTWlsZXN0b25lTWFuZGF0b3J5Q29tcGxldGVcclxuICAgICAgICAgIGNvbnNvbGUubG9nKGAgICBGYWxsYmFjayBjaGVjazogbWFuZGF0b3J5PSR7aXNQcmV2aW91c01pbGVzdG9uZU1hbmRhdG9yeUNvbXBsZXRlfSwgYXNzZXNzbWVudD0ke2lzUHJldmlvdXNNaWxlc3RvbmVBc3Nlc3NtZW50Q29tcGxldGV9YClcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGlzTG9ja2VkID0gIXByZXZpb3VzTWlsZXN0b25lQ29tcGxldGVcclxuICAgICAgICB0aGlzLmhhc2htYXBbbWlsZXN0b25lSWRdLmNvbXB1dGVkSXNMb2NrZWQgPSBpc0xvY2tlZFxyXG4gICAgICAgIHRoaXMuaGFzaG1hcFttaWxlc3RvbmVJZF0udW5sb2NrTWVzc2FnZSA9IGlzTG9ja2VkID9cclxuICAgICAgICAgIGBDb21wbGV0ZSBhbGwgbWFuZGF0b3J5IGNvbnRlbnQgYW5kIGFzc2Vzc21lbnQgaW4gTWlsZXN0b25lICR7aW5kZXh9IHRvIHVubG9jayB0aGlzIG1pbGVzdG9uZWAgOiAnJ1xyXG4gICAgICAgIFxyXG4gICAgICAgIGNvbnNvbGUubG9nKGAgICAke2lzTG9ja2VkID8gJ/CflJIgTE9DS0VEJyA6ICfwn5STIFVOTE9DS0VEJ31gKVxyXG4gICAgICAgIGNvbnNvbGUubG9nKGAgICBSZWFzb246IFByZXZpb3VzIG1pbGVzdG9uZSAke3ByZXZpb3VzTWlsZXN0b25lQ29tcGxldGUgPyAnY29tcGxldGUnIDogJ2luY29tcGxldGUnfWApXHJcbiAgICAgICAgY29uc29sZS5sb2coYCAgIFByZXZpb3VzIE0ke2luZGV4fSBwcm9ncmVzczogJHtwcmV2Q29tcGxldGlvblBjdH0lYClcclxuICAgICAgICBcclxuICAgICAgICAvLyBGb3IgdW5sb2NrZWQgbWlsZXN0b25lcywgY2hlY2sgYXNzZXNzbWVudCBsb2NraW5nXHJcbiAgICAgICAgaWYgKCFpc0xvY2tlZCkge1xyXG4gICAgICAgICAgY29uc29sZS5sb2coYCAgIOKckyBDaGVja2luZyBhc3Nlc3NtZW50IGxvY2suLi5gKVxyXG4gICAgICAgICAgdGhpcy5jb21wdXRlQXNzZXNzbWVudExvY2tpbmdJbk1pbGVzdG9uZShtaWxlc3RvbmVJZClcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgY29uc29sZS5sb2coYCAgIOKoryBNaWxlc3RvbmUgbG9ja2VkIC0gbWFya2luZyBhbGwgY2hpbGRyZW4gYXMgcGFyZW50LWxvY2tlZGApXHJcbiAgICAgICAgICB0aGlzLm1hcmtNaWxlc3RvbmVDaGlsZHJlbkFzUGFyZW50TG9ja2VkKG1pbGVzdG9uZUlkLCB0cnVlKVxyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLmhhc2htYXBbbWlsZXN0b25lSWRdLmNvbXB1dGVkSXNMb2NrZWQgPSB0cnVlXHJcbiAgICAgICAgdGhpcy5oYXNobWFwW21pbGVzdG9uZUlkXS51bmxvY2tNZXNzYWdlID0gJ1ByZXZpb3VzIG1pbGVzdG9uZSBub3QgZm91bmQnXHJcbiAgICAgICAgY29uc29sZS5sb2coYCAgIPCflJIgTE9DS0VEIChwcmV2aW91cyBtaWxlc3RvbmUgbm90IGZvdW5kKWApXHJcbiAgICAgIH1cclxuICAgIH0pXHJcblxyXG4gICAgLy8gU1RFUCA1OiBDb21wdXRlIHBhcmVudCBtaWxlc3RvbmUgbG9jayBzdGF0dXMgZm9yIEFMTCBjaGlsZHJlblxyXG4gICAgY29uc29sZS5sb2coJ1xcbvCflJcgQ29tcHV0aW5nIHBhcmVudCBtaWxlc3RvbmUgbG9ja3MgZm9yIGFsbCBjaGlsZHJlbi4uLicpXHJcbiAgICBPYmplY3Qua2V5cyh0aGlzLmhhc2htYXApLmZvckVhY2goa2V5ID0+IHtcclxuICAgICAgY29uc3QgaXRlbSA9IHRoaXMuaGFzaG1hcFtrZXldXHJcbiAgICAgIGlmIChpdGVtLmlzTWlsZXN0b25lKSByZXR1cm4gLy8gU2tpcCBtaWxlc3RvbmVzIHRoZW1zZWx2ZXNcclxuXHJcbiAgICAgIC8vIFRyYXZlcnNlIHVwIHRvIGZpbmQgaWYgYW55IGFuY2VzdG9yIG1pbGVzdG9uZSBpcyBsb2NrZWRcclxuICAgICAgbGV0IGN1cnJlbnRQYXJlbnRJZCA9IGl0ZW0ucGFyZW50XHJcbiAgICAgIGxldCBkZXB0aCA9IDBcclxuICAgICAgY29uc3QgbWF4RGVwdGggPSA1XHJcbiAgICAgIGxldCBmb3VuZExvY2tlZFBhcmVudCA9IGZhbHNlXHJcblxyXG4gICAgICB3aGlsZSAoY3VycmVudFBhcmVudElkICYmIGRlcHRoIDwgbWF4RGVwdGgpIHtcclxuICAgICAgICBjb25zdCBwYXJlbnREYXRhID0gdGhpcy5oYXNobWFwW2N1cnJlbnRQYXJlbnRJZF1cclxuICAgICAgICBpZiAocGFyZW50RGF0YSkge1xyXG4gICAgICAgICAgaWYgKHBhcmVudERhdGEuaXNNaWxlc3RvbmUgJiYgcGFyZW50RGF0YS5jb21wdXRlZElzTG9ja2VkKSB7XHJcbiAgICAgICAgICAgIHRoaXMuaGFzaG1hcFtrZXldLmlzUGFyZW50TWlsZXN0b25lTG9ja2VkID0gdHJ1ZVxyXG4gICAgICAgICAgICBmb3VuZExvY2tlZFBhcmVudCA9IHRydWVcclxuICAgICAgICAgICAgYnJlYWtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGN1cnJlbnRQYXJlbnRJZCA9IHBhcmVudERhdGEucGFyZW50XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGJyZWFrXHJcbiAgICAgICAgfVxyXG4gICAgICAgIGRlcHRoKytcclxuICAgICAgfVxyXG4gICAgICBcclxuICAgICAgaWYgKCFmb3VuZExvY2tlZFBhcmVudCkge1xyXG4gICAgICAgIHRoaXMuaGFzaG1hcFtrZXldLmlzUGFyZW50TWlsZXN0b25lTG9ja2VkID0gZmFsc2VcclxuICAgICAgfVxyXG4gICAgfSlcclxuXHJcbiAgICAvLyBTVEVQIDY6IFRyaWdnZXIgaGFzaG1hcCB1cGRhdGVcclxuICAgIGNvbnNvbGUubG9nKCdcXG7ilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAnKVxyXG4gICAgY29uc29sZS5sb2coJ+KchSBNaWxlc3RvbmUgbG9ja2luZyBjb21wdXRhdGlvbiBDT01QTEVURScpXHJcbiAgICBjb25zb2xlLmxvZygn4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQXFxuJylcclxuICAgIFxyXG4gICAgdGhpcy5oYXNobWFwID0geyAuLi50aGlzLmhhc2htYXAgfVxyXG4gICAgdGhpcy5oYXNobWFwVXBkYXRlZC5uZXh0KHsgdGltZXN0YW1wOiBEYXRlLm5vdygpLCBoYXNobWFwOiB0aGlzLmhhc2htYXAgfSlcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFRyaWdnZXIgbWlsZXN0b25lIGxvY2sgdXBkYXRlIHdoZW4gaGFzaG1hcCBwcm9ncmVzcyBpcyB1cGRhdGVkIGV4dGVybmFsbHlcclxuICAgKiBDYWxsZWQgZnJvbSB2aWV3ZXItdXRpbC5zZXJ2aWNlLnRzIGFmdGVyIHByb2dyZXNzIHVwZGF0ZXNcclxuICAgKi9cclxuICBwdWJsaWMgdHJpZ2dlck1pbGVzdG9uZUxvY2tVcGRhdGUoKSB7XHJcbiAgICAvLyBDaGVjayBpZiB3ZSBoYXZlIGEgTGVhcm5pbmcgUGF0aHdheSBpbiB0aGUgaGFzaG1hcFxyXG4gICAgY29uc3QgaGFzTGVhcm5pbmdQYXRod2F5ID0gT2JqZWN0LmtleXModGhpcy5oYXNobWFwKS5zb21lKGtleSA9PiB7XHJcbiAgICAgIGNvbnN0IGl0ZW0gPSB0aGlzLmhhc2htYXBba2V5XVxyXG4gICAgICByZXR1cm4gaXRlbS5pc0xlYXJuaW5nUGF0aHdheSAmJiBpdGVtLmNvdXJzZUNhdGVnb3J5ID09PSAnTGVhcm5pbmcgUGF0aHdheSdcclxuICAgIH0pXHJcbiAgICBcclxuICAgIGlmIChoYXNMZWFybmluZ1BhdGh3YXkpIHtcclxuICAgICAgY29uc29sZS5sb2coJ/CflIQgVHJpZ2dlcmluZyBtaWxlc3RvbmUgbG9jayByZWNvbXB1dGF0aW9uIGFmdGVyIHByb2dyZXNzIHVwZGF0ZScpXHJcbiAgICAgIC8vIEFzc3VtZSBlbnJvbGxlZCBzaW5jZSBwcm9ncmVzcyB3YXMganVzdCB1cGRhdGVkXHJcbiAgICAgIHRoaXMuY29tcHV0ZU1pbGVzdG9uZUxvY2tpbmdTdGF0dXModHJ1ZSlcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrIGlmIHByZS1hc3Nlc3NtZW50IChwcmVsaW1pbmFyeSBhc3Nlc3NtZW50KSBpcyBjb21wbGV0ZWRcclxuICAgKiBQcmUtYXNzZXNzbWVudCBpcyB0eXBpY2FsbHkgYSBDb3Vyc2UgQXNzZXNzbWVudCBhdCB0aGUgcm9vdCBsZXZlbCBvZiBMZWFybmluZyBQYXRod2F5IChiZWZvcmUgbWlsZXN0b25lcylcclxuICAgKi9cclxuICBwcml2YXRlIGNoZWNrUHJlQXNzZXNzbWVudENvbXBsZXRpb24oKTogYm9vbGVhbiB7XHJcbiAgICAvLyBGaW5kIHRoZSBMZWFybmluZyBQYXRod2F5IHJvb3RcclxuICAgIGxldCBsZWFybmluZ1BhdGh3YXlJZDogc3RyaW5nIHwgbnVsbCA9IG51bGxcclxuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHRoaXMuaGFzaG1hcCkpIHtcclxuICAgICAgY29uc3QgaXRlbSA9IHRoaXMuaGFzaG1hcFtrZXldXHJcbiAgICAgIGlmIChpdGVtLmlzTGVhcm5pbmdQYXRod2F5ICYmIGl0ZW0uY291cnNlQ2F0ZWdvcnkgPT09ICdMZWFybmluZyBQYXRod2F5Jykge1xyXG4gICAgICAgIGxlYXJuaW5nUGF0aHdheUlkID0ga2V5XHJcbiAgICAgICAgYnJlYWtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGNvbnNvbGUubG9nKCdDaGVja2luZyBwcmUtYXNzZXNzbWVudCBjb21wbGV0aW9uLiBMZWFybmluZyBQYXRod2F5IElEOicsIGxlYXJuaW5nUGF0aHdheUlkKVxyXG5cclxuICAgIC8vIFBSSU9SSVRZIDE6IExvb2sgZm9yIGl0ZW1zIGV4cGxpY2l0bHkgbWFya2VkIGFzIHByZS1hc3Nlc3NtZW50XHJcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyh0aGlzLmhhc2htYXApKSB7XHJcbiAgICAgIGNvbnN0IGl0ZW0gPSB0aGlzLmhhc2htYXBba2V5XVxyXG4gICAgICBpZiAoaXRlbS5pc1ByZUFzc2Vzc21lbnQgPT09IHRydWUpIHtcclxuICAgICAgICAvLyBNdXN0IGNoZWNrIGZvciBhY3R1YWwgY29tcGxldGlvbiAtIG5vdCBqdXN0IGFueSB2YWx1ZVxyXG4gICAgICAgIGNvbnN0IGlzQ29tcGxldGVkID0gKGl0ZW0uY29tcGxldGlvblN0YXR1cyA9PT0gMiB8fCBpdGVtLnN0YXR1cyA9PT0gMiB8fCBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpdGVtLmNvbXBsZXRpb25QZXJjZW50YWdlICE9PSB1bmRlZmluZWQgJiYgaXRlbS5jb21wbGV0aW9uUGVyY2VudGFnZSA+PSAxMDApIHx8IFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGl0ZW0ucHJvZ3Jlc3MgIT09IHVuZGVmaW5lZCAmJiBpdGVtLnByb2dyZXNzID49IDEwMCkpXHJcbiAgICAgICAgY29uc29sZS5sb2coYOKchSBQcmUtYXNzZXNzbWVudCBmb3VuZCAoaXNQcmVBc3Nlc3NtZW50IGZsYWcpOiAke2tleX1gLCB7XHJcbiAgICAgICAgICBuYW1lOiBpdGVtLm5hbWUsXHJcbiAgICAgICAgICBjb21wbGV0aW9uU3RhdHVzOiBpdGVtLmNvbXBsZXRpb25TdGF0dXMsXHJcbiAgICAgICAgICBzdGF0dXM6IGl0ZW0uc3RhdHVzLFxyXG4gICAgICAgICAgY29tcGxldGlvblBlcmNlbnRhZ2U6IGl0ZW0uY29tcGxldGlvblBlcmNlbnRhZ2UsXHJcbiAgICAgICAgICBwcm9ncmVzczogaXRlbS5wcm9ncmVzcyxcclxuICAgICAgICAgIGlzQ29tcGxldGVkLFxyXG4gICAgICAgICAgLy8gU2hvdyBBTEwgZmllbGRzIHRvIGRlYnVnIHdoYXQncyBhdmFpbGFibGVcclxuICAgICAgICAgIGFsbERhdGE6IEpTT04uc3RyaW5naWZ5KGl0ZW0sIG51bGwsIDIpXHJcbiAgICAgICAgfSlcclxuICAgICAgICAvLyBQcmUtYXNzZXNzbWVudCBleGlzdHMgLSByZXR1cm4gaXRzIGNvbXBsZXRpb24gc3RhdHVzICh0cnVlL2ZhbHNlKVxyXG4gICAgICAgIHJldHVybiBpc0NvbXBsZXRlZFxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gUFJJT1JJVFkgMjogRmluZCBwcmUtYXNzZXNzbWVudCBpbiBoYXNobWFwIC0gZGlyZWN0IGNoaWxkIG9mIExlYXJuaW5nIFBhdGh3YXkgdGhhdCBpcyBOT1QgYSBtaWxlc3RvbmVcclxuICAgIC8vIENoZWNrIGZvciBmaXJzdCBub24tbWlsZXN0b25lIGNoaWxkIG9mIExlYXJuaW5nIFBhdGh3YXlcclxuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHRoaXMuaGFzaG1hcCkpIHtcclxuICAgICAgY29uc3QgaXRlbSA9IHRoaXMuaGFzaG1hcFtrZXldXHJcblxyXG4gICAgICAvLyBDaGVjayBpZiB0aGlzIGlzIGEgZGlyZWN0IGNoaWxkIG9mIHRoZSBMZWFybmluZyBQYXRod2F5XHJcbiAgICAgIGlmIChpdGVtLnBhcmVudCAhPT0gbGVhcm5pbmdQYXRod2F5SWQpIGNvbnRpbnVlXHJcblxyXG4gICAgICAvLyBTa2lwIG1pbGVzdG9uZXNcclxuICAgICAgaWYgKGl0ZW0uaXNNaWxlc3RvbmUpIGNvbnRpbnVlXHJcblxyXG4gICAgICAvLyBUaGlzIGlzIGEgbm9uLW1pbGVzdG9uZSBkaXJlY3QgY2hpbGQgLSBpdCdzIHRoZSBwcmUtYXNzZXNzbWVudFxyXG4gICAgICAvLyBNdXN0IGNoZWNrIGZvciBhY3R1YWwgY29tcGxldGlvbiAtIG5vdCBqdXN0IGFueSB2YWx1ZVxyXG4gICAgICBjb25zdCBpc0NvbXBsZXRlZCA9IChpdGVtLmNvbXBsZXRpb25TdGF0dXMgPT09IDIgfHwgaXRlbS5zdGF0dXMgPT09IDIgfHwgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKGl0ZW0uY29tcGxldGlvblBlcmNlbnRhZ2UgIT09IHVuZGVmaW5lZCAmJiBpdGVtLmNvbXBsZXRpb25QZXJjZW50YWdlID49IDEwMCkgfHwgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKGl0ZW0ucHJvZ3Jlc3MgIT09IHVuZGVmaW5lZCAmJiBpdGVtLnByb2dyZXNzID49IDEwMCkpXHJcbiAgICAgIGNvbnNvbGUubG9nKGDinIUgUHJlLWFzc2Vzc21lbnQgZm91bmQgKGZpcnN0IG5vbi1taWxlc3RvbmUgY2hpbGQpOiAke2tleX1gLCB7XHJcbiAgICAgICAgbmFtZTogaXRlbS5uYW1lLFxyXG4gICAgICAgIGNvbXBsZXRpb25TdGF0dXM6IGl0ZW0uY29tcGxldGlvblN0YXR1cyxcclxuICAgICAgICBzdGF0dXM6IGl0ZW0uc3RhdHVzLFxyXG4gICAgICAgIGNvbXBsZXRpb25QZXJjZW50YWdlOiBpdGVtLmNvbXBsZXRpb25QZXJjZW50YWdlLFxyXG4gICAgICAgIHByb2dyZXNzOiBpdGVtLnByb2dyZXNzLFxyXG4gICAgICAgIGlzQ29tcGxldGVkLFxyXG4gICAgICAgIC8vIFNob3cgQUxMIGZpZWxkcyB0byBkZWJ1ZyB3aGF0J3MgYXZhaWxhYmxlXHJcbiAgICAgICAgYWxsRGF0YTogSlNPTi5zdHJpbmdpZnkoaXRlbSwgbnVsbCwgMilcclxuICAgICAgfSlcclxuICAgICAgLy8gUHJlLWFzc2Vzc21lbnQgZXhpc3RzIC0gcmV0dXJuIGl0cyBjb21wbGV0aW9uIHN0YXR1cyAodHJ1ZS9mYWxzZSlcclxuICAgICAgcmV0dXJuIGlzQ29tcGxldGVkXHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ1JJVElDQUw6IElmIHdlIHJlYWNoIGhlcmUsIG5vIHByZS1hc3Nlc3NtZW50IHdhcyBmb3VuZCBpbiB0aGUgaGFzaG1hcFxyXG4gICAgLy8gVGhpcyBjb3VsZCBtZWFuIGVpdGhlcjpcclxuICAgIC8vIDEuIFRoZXJlIElTIG5vIHByZS1hc3Nlc3NtZW50ICh1bmxvY2sgTTEgYnkgZGVmYXVsdClcclxuICAgIC8vIDIuIFRoZSBoYXNobWFwIGhhc24ndCBiZWVuIHBvcHVsYXRlZCB5ZXQgKHNob3VsZCBsb2NrIE0xIHVudGlsIGRhdGEgaXMgcmVhZHkpXHJcbiAgICBcclxuICAgIC8vIFRvIGJlIHNhZmUsIGNoZWNrIGlmIEFOWSBjaGlsZHJlbiBleGlzdCBhdCBhbGxcclxuICAgIGNvbnN0IGhhc0FueUNoaWxkcmVuID0gT2JqZWN0LmtleXModGhpcy5oYXNobWFwKS5zb21lKGtleSA9PiBcclxuICAgICAgdGhpcy5oYXNobWFwW2tleV0ucGFyZW50ID09PSBsZWFybmluZ1BhdGh3YXlJZFxyXG4gICAgKVxyXG4gICAgXHJcbiAgICBpZiAoIWhhc0FueUNoaWxkcmVuKSB7XHJcbiAgICAgIC8vIEhhc2htYXAgbm90IHBvcHVsYXRlZCB5ZXQgLSBsb2NrIE0xIHVudGlsIGRhdGEgaXMgcmVhZHlcclxuICAgICAgY29uc29sZS5sb2coJ+KaoO+4jyBObyBjaGlsZHJlbiBmb3VuZCBpbiBoYXNobWFwIHlldCAtIGxvY2tpbmcgTTEgdW50aWwgZGF0YSBpcyByZWFkeScpXHJcbiAgICAgIHJldHVybiBmYWxzZVxyXG4gICAgfVxyXG4gICAgXHJcbiAgICAvLyBIYXNobWFwIGlzIHBvcHVsYXRlZCBidXQgbm8gcHJlLWFzc2Vzc21lbnQgZm91bmQgLSBhbGxvdyBNMSB0byB1bmxvY2tcclxuICAgIGNvbnNvbGUubG9nKCdObyBwcmUtYXNzZXNzbWVudCBmb3VuZCBpbiBmdWxseSBwb3B1bGF0ZWQgaGFzaG1hcCAtIGFsbG93aW5nIE0xIHRvIGJlIHVubG9ja2VkIGJ5IGRlZmF1bHQnKVxyXG4gICAgcmV0dXJuIHRydWVcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrIGlmIGEgbWlsZXN0b25lJ3MgYXNzZXNzbWVudCBpcyBjb21wbGV0ZWRcclxuICAgKiBTZWFyY2hlcyBmb3IgYW55IGFzc2Vzc21lbnQgdHlwZSAoQ291cnNlIEFzc2Vzc21lbnQsIEZpbmFsIEFzc2Vzc21lbnQsIGV0Yy4pIHRoYXQgYmVsb25ncyB0byB0aGlzIG1pbGVzdG9uZVxyXG4gICAqL1xyXG4gIHByaXZhdGUgY2hlY2tNaWxlc3RvbmVBc3Nlc3NtZW50Q29tcGxldGUobWlsZXN0b25lSWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgY29uc3QgbWlsZXN0b25lID0gdGhpcy5oYXNobWFwW21pbGVzdG9uZUlkXVxyXG5cclxuICAgIC8vIENoZWNrIGFsbCBpdGVtcyBpbiBoYXNobWFwIHRoYXQgYXJlIGFzc2Vzc21lbnRzIGFuZCBiZWxvbmcgdG8gdGhpcyBtaWxlc3RvbmVcclxuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHRoaXMuaGFzaG1hcCkpIHtcclxuICAgICAgY29uc3QgaXRlbSA9IHRoaXMuaGFzaG1hcFtrZXldXHJcblxyXG4gICAgICAvLyBDaGVjayBpZiB0aGlzIGlzIGFuIGFzc2Vzc21lbnQgdHlwZVxyXG4gICAgICBjb25zdCBpc0Fzc2Vzc21lbnRUeXBlID1cclxuICAgICAgICBpdGVtLnByaW1hcnlDYXRlZ29yeSA9PT0gJ0NvdXJzZSBBc3Nlc3NtZW50JyB8fFxyXG4gICAgICAgIGl0ZW0ucHJpbWFyeUNhdGVnb3J5ID09PSAnRmluYWwgQXNzZXNzbWVudCcgfHxcclxuICAgICAgICBpdGVtLnByaW1hcnlDYXRlZ29yeSA9PT0gJ1ByYWN0aWNlIFF1ZXN0aW9uIFNldCcgfHxcclxuICAgICAgICBpdGVtLmNvdXJzZUNhdGVnb3J5ID09PSAnQ291cnNlIEFzc2Vzc21lbnQnIHx8XHJcbiAgICAgICAgaXRlbS5jb3Vyc2VDYXRlZ29yeSA9PT0gJ0ZpbmFsIEFzc2Vzc21lbnQnIHx8XHJcbiAgICAgICAgKGl0ZW0ubmFtZSAmJiBpdGVtLm5hbWUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnYXNzZXNzbWVudCcpKVxyXG5cclxuICAgICAgaWYgKCFpc0Fzc2Vzc21lbnRUeXBlKSBjb250aW51ZVxyXG5cclxuICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBhc3Nlc3NtZW50IGJlbG9uZ3MgdG8gdGhpcyBtaWxlc3RvbmVcclxuICAgICAgaWYgKHRoaXMuaXNDaGlsZE9mTWlsZXN0b25lKGtleSwgbWlsZXN0b25lSWQpKSB7XHJcbiAgICAgICAgY29uc3QgaXNDb21wbGV0ZWQgPSBpdGVtLmNvbXBsZXRpb25TdGF0dXMgPT09IDIgfHwgaXRlbS5zdGF0dXMgPT09IDIgfHwgaXRlbS5jb21wbGV0aW9uUGVyY2VudGFnZSA+PSAxMDAgfHwgaXRlbS5wcm9ncmVzcyA+PSAxMDBcclxuICAgICAgICBpZiAoaXNDb21wbGV0ZWQpIHtcclxuICAgICAgICAgIHJldHVybiB0cnVlXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gSWYgbm8gYXNzZXNzbWVudCBmb3VuZCwgY29uc2lkZXIgaXQgYXMgY29tcGxldGVkIChubyBhc3Nlc3NtZW50IHJlcXVpcmVtZW50KVxyXG4gICAgcmV0dXJuIHRydWVcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrIGlmIGEgbWlsZXN0b25lJ3MgbWFuZGF0b3J5IGNvbnRlbnQgaXMgY29tcGxldGVkXHJcbiAgICogT25seSBjaGVja3MgY291cnNlcy9jb250ZW50IHRoYXQgYXJlIG1hcmtlZCBhcyBpc01hbmRhdG9yeVxyXG4gICAqL1xyXG4gIHByaXZhdGUgY2hlY2tNaWxlc3RvbmVNYW5kYXRvcnlDb250ZW50Q29tcGxldGUobWlsZXN0b25lSWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgY29uc3QgbWlsZXN0b25lID0gdGhpcy5oYXNobWFwW21pbGVzdG9uZUlkXVxyXG5cclxuICAgIGxldCBtYW5kYXRvcnlDb3VudCA9IDBcclxuICAgIGxldCBjb21wbGV0ZWRNYW5kYXRvcnlDb3VudCA9IDBcclxuXHJcbiAgICAvLyBDaGVjayBhbGwgaXRlbXMgaW4gaGFzaG1hcCB0aGF0IGFyZSBkaXJlY3QgY2hpbGRyZW4gb2YgdGhpcyBtaWxlc3RvbmUgKGNvdXJzZXMpXHJcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyh0aGlzLmhhc2htYXApKSB7XHJcbiAgICAgIGNvbnN0IGl0ZW0gPSB0aGlzLmhhc2htYXBba2V5XVxyXG5cclxuICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpdGVtIGlzIGEgZGlyZWN0IGNoaWxkIG9mIHRoZSBtaWxlc3RvbmUgKGNvdXJzZSBsZXZlbClcclxuICAgICAgaWYgKGl0ZW0ucGFyZW50ICE9PSBtaWxlc3RvbmVJZCkgY29udGludWVcclxuXHJcbiAgICAgIC8vIFNraXAgaWYgbm90IGEgY291cnNlIG9yIGNvbGxlY3Rpb25cclxuICAgICAgaWYgKGl0ZW0ucHJpbWFyeUNhdGVnb3J5ICE9PSAnQ291cnNlJyAmJiAhaXRlbS5pc0NvbGxlY3Rpb24pIGNvbnRpbnVlXHJcblxyXG4gICAgICAvLyBTa2lwIGFzc2Vzc21lbnRzIC0gdGhleSdyZSBjaGVja2VkIHNlcGFyYXRlbHlcclxuICAgICAgY29uc3QgaXNBc3Nlc3NtZW50ID1cclxuICAgICAgICBpdGVtLnByaW1hcnlDYXRlZ29yeSA9PT0gJ0NvdXJzZSBBc3Nlc3NtZW50JyB8fFxyXG4gICAgICAgIGl0ZW0ucHJpbWFyeUNhdGVnb3J5ID09PSAnRmluYWwgQXNzZXNzbWVudCcgfHxcclxuICAgICAgICBpdGVtLmNvdXJzZUNhdGVnb3J5ID09PSAnQ291cnNlIEFzc2Vzc21lbnQnIHx8XHJcbiAgICAgICAgKGl0ZW0ubmFtZSAmJiBpdGVtLm5hbWUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnYXNzZXNzbWVudCcpKVxyXG4gICAgICBpZiAoaXNBc3Nlc3NtZW50KSBjb250aW51ZVxyXG5cclxuICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBjb250ZW50IGlzIG1hbmRhdG9yeVxyXG4gICAgICBpZiAoaXRlbS5pc01hbmRhdG9yeSkge1xyXG4gICAgICAgIG1hbmRhdG9yeUNvdW50KytcclxuICAgICAgICBjb25zdCBpc0NvbXBsZXRlZCA9IGl0ZW0uY29tcGxldGlvblN0YXR1cyA9PT0gMiB8fCBpdGVtLnN0YXR1cyA9PT0gMiB8fCBpdGVtLmNvbXBsZXRpb25QZXJjZW50YWdlID49IDEwMCB8fCBpdGVtLnByb2dyZXNzID49IDEwMFxyXG4gICAgICAgIGlmIChpc0NvbXBsZXRlZCkge1xyXG4gICAgICAgICAgY29tcGxldGVkTWFuZGF0b3J5Q291bnQrK1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGFsbENvbXBsZXRlID0gbWFuZGF0b3J5Q291bnQgPT09IDAgfHwgY29tcGxldGVkTWFuZGF0b3J5Q291bnQgPj0gbWFuZGF0b3J5Q291bnRcclxuICAgIHJldHVybiBhbGxDb21wbGV0ZVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2hlY2sgaWYgYSBjb250ZW50IGl0ZW0gaXMgYSBjaGlsZCAoZGlyZWN0IG9yIG5lc3RlZCkgb2YgYSBtaWxlc3RvbmVcclxuICAgKi9cclxuICBwcml2YXRlIGlzQ2hpbGRPZk1pbGVzdG9uZShjb250ZW50SWQ6IHN0cmluZywgbWlsZXN0b25lSWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgbGV0IGN1cnJlbnRJZCA9IGNvbnRlbnRJZFxyXG4gICAgbGV0IGRlcHRoID0gMFxyXG4gICAgY29uc3QgbWF4RGVwdGggPSAxMFxyXG5cclxuICAgIHdoaWxlIChjdXJyZW50SWQgJiYgZGVwdGggPCBtYXhEZXB0aCkge1xyXG4gICAgICBjb25zdCBpdGVtID0gdGhpcy5oYXNobWFwW2N1cnJlbnRJZF1cclxuICAgICAgaWYgKCFpdGVtKSByZXR1cm4gZmFsc2VcclxuICAgICAgaWYgKGl0ZW0ucGFyZW50ID09PSBtaWxlc3RvbmVJZCkgcmV0dXJuIHRydWVcclxuICAgICAgY3VycmVudElkID0gaXRlbS5wYXJlbnRcclxuICAgICAgZGVwdGgrK1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGZhbHNlXHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDb21wdXRlIGFzc2Vzc21lbnQgbG9ja2luZyB3aXRoaW4gYW4gdW5sb2NrZWQgbWlsZXN0b25lXHJcbiAgICogQXNzZXNzbWVudCBsb2NrcyB1bnRpbCBhbGwgbWFuZGF0b3J5IGNvdXJzZXMgaW4gdGhlIG1pbGVzdG9uZSBhcmUgY29tcGxldGVkXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBjb21wdXRlQXNzZXNzbWVudExvY2tpbmdJbk1pbGVzdG9uZShtaWxlc3RvbmVJZDogc3RyaW5nKTogdm9pZCB7XHJcbiAgICBjb25zdCBtaWxlc3RvbmUgPSB0aGlzLmhhc2htYXBbbWlsZXN0b25lSWRdXHJcbiAgICBpZiAoIW1pbGVzdG9uZSkgcmV0dXJuXHJcblxyXG4gICAgY29uc29sZS5sb2coYENvbXB1dGluZyBhc3Nlc3NtZW50IGxvY2tpbmcgZm9yIG1pbGVzdG9uZTogJHttaWxlc3RvbmVJZH1gKVxyXG5cclxuICAgIC8vIEZpbmQgYXNzZXNzbWVudCBpbiB0aGlzIG1pbGVzdG9uZVxyXG4gICAgbGV0IGFzc2Vzc21lbnRJZDogc3RyaW5nIHwgbnVsbCA9IG51bGxcclxuICAgIGxldCBhc3Nlc3NtZW50OiBhbnkgPSBudWxsXHJcblxyXG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXModGhpcy5oYXNobWFwKSkge1xyXG4gICAgICBjb25zdCBpdGVtID0gdGhpcy5oYXNobWFwW2tleV1cclxuICAgICAgXHJcbiAgICAgIC8vIENoZWNrIGlmIHRoaXMgaXMgYW4gYXNzZXNzbWVudCB0aGF0IGJlbG9uZ3MgdG8gdGhpcyBtaWxlc3RvbmVcclxuICAgICAgLy8gTXVzdCBoYXZlIEJPVEg6IGNvcnJlY3QgY2F0ZWdvcnkvbWltZVR5cGUgQU5EIHBhcmVudCBpcyBtaWxlc3RvbmVcclxuICAgICAgY29uc3QgaXNBc3Nlc3NtZW50ID0gKFxyXG4gICAgICAgIGl0ZW0ucHJpbWFyeUNhdGVnb3J5ID09PSAnQ291cnNlIEFzc2Vzc21lbnQnIHx8XHJcbiAgICAgICAgaXRlbS5wcmltYXJ5Q2F0ZWdvcnkgPT09ICdGaW5hbCBBc3Nlc3NtZW50JyB8fFxyXG4gICAgICAgIGl0ZW0ucHJpbWFyeUNhdGVnb3J5ID09PSAnU3RhbmRhbG9uZSBBc3Nlc3NtZW50JyB8fFxyXG4gICAgICAgIGl0ZW0ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi92bmQuc3VuYmlyZC5xdWVzdGlvbnNldCcgfHxcclxuICAgICAgICBpdGVtLm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vcXVpeidcclxuICAgICAgKSAmJiBpdGVtLnBhcmVudCA9PT0gbWlsZXN0b25lSWQgIC8vIE1VU1QgYmUgZGlyZWN0IGNoaWxkIG9mIG1pbGVzdG9uZVxyXG5cclxuICAgICAgaWYgKGlzQXNzZXNzbWVudCkge1xyXG4gICAgICAgIGFzc2Vzc21lbnRJZCA9IGtleVxyXG4gICAgICAgIGFzc2Vzc21lbnQgPSBpdGVtXHJcbiAgICAgICAgY29uc29sZS5sb2coYOKchSBGb3VuZCBtaWxlc3RvbmUgYXNzZXNzbWVudDogJHtpdGVtLm5hbWV9ICgke2tleX0pYClcclxuICAgICAgICBicmVha1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCFhc3Nlc3NtZW50SWQgfHwgIWFzc2Vzc21lbnQpIHtcclxuICAgICAgY29uc29sZS5sb2coYE5vIGFzc2Vzc21lbnQgZm91bmQgaW4gbWlsZXN0b25lICR7bWlsZXN0b25lSWR9YClcclxuICAgICAgcmV0dXJuXHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ2hlY2sgaWYgYXNzZXNzbWVudCBpcyBhbHJlYWR5IGNvbXBsZXRlZCAtIHJlLXJlYWQgZnJvbSBoYXNobWFwIHRvIGdldCBsYXRlc3QgZGF0YVxyXG4gICAgY29uc3QgbGF0ZXN0QXNzZXNzbWVudCA9IHRoaXMuaGFzaG1hcFthc3Nlc3NtZW50SWRdXHJcbiAgICBjb25zdCBhc3Nlc3NtZW50Q29tcGxldGVkID0gXHJcbiAgICAgIGxhdGVzdEFzc2Vzc21lbnQuY29tcGxldGlvblN0YXR1cyA9PT0gMiB8fCBcclxuICAgICAgbGF0ZXN0QXNzZXNzbWVudC5zdGF0dXMgPT09IDIgfHwgXHJcbiAgICAgIGxhdGVzdEFzc2Vzc21lbnQuY29tcGxldGlvblBlcmNlbnRhZ2UgPj0gMTAwXHJcblxyXG4gICAgaWYgKGFzc2Vzc21lbnRDb21wbGV0ZWQpIHtcclxuICAgICAgdGhpcy5oYXNobWFwW2Fzc2Vzc21lbnRJZF0uaXNBc3Nlc3NtZW50TG9ja2VkID0gZmFsc2VcclxuICAgICAgdGhpcy5oYXNobWFwW2Fzc2Vzc21lbnRJZF0uYXNzZXNzbWVudExvY2tNZXNzYWdlID0gJydcclxuICAgICAgY29uc29sZS5sb2coYEFzc2Vzc21lbnQgJHthc3Nlc3NtZW50SWR9IGlzIGNvbXBsZXRlZCAtIHVubG9ja2luZ2ApXHJcbiAgICAgIHJldHVyblxyXG4gICAgfVxyXG5cclxuICAgIC8vIENvdW50IG1hbmRhdG9yeSBjb3Vyc2VzIGFuZCBjaGVjayB0aGVpciBjb21wbGV0aW9uXHJcbiAgICBsZXQgbWFuZGF0b3J5Q291bnQgPSAwXHJcbiAgICBsZXQgY29tcGxldGVkTWFuZGF0b3J5Q291bnQgPSAwXHJcblxyXG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXModGhpcy5oYXNobWFwKSkge1xyXG4gICAgICBjb25zdCBpdGVtID0gdGhpcy5oYXNobWFwW2tleV1cclxuXHJcbiAgICAgIC8vIFNraXAgdGhlIGFzc2Vzc21lbnQgaXRzZWxmXHJcbiAgICAgIGlmIChrZXkgPT09IGFzc2Vzc21lbnRJZCkgY29udGludWVcclxuXHJcbiAgICAgIC8vIENoZWNrIGlmIGl0ZW0gYmVsb25ncyB0byB0aGlzIG1pbGVzdG9uZVxyXG4gICAgICBsZXQgYmVsb25nc1RvTWlsZXN0b25lID0gZmFsc2VcclxuICAgICAgaWYgKGl0ZW0ucGFyZW50ID09PSBtaWxlc3RvbmVJZCkge1xyXG4gICAgICAgIGJlbG9uZ3NUb01pbGVzdG9uZSA9IHRydWVcclxuICAgICAgfSBlbHNlIGlmIChpdGVtLnBhcmVudCAmJiB0aGlzLmhhc2htYXBbaXRlbS5wYXJlbnRdKSB7XHJcbiAgICAgICAgY29uc3QgcGFyZW50SXRlbSA9IHRoaXMuaGFzaG1hcFtpdGVtLnBhcmVudF1cclxuICAgICAgICBpZiAocGFyZW50SXRlbS5wYXJlbnQgPT09IG1pbGVzdG9uZUlkICYmIHBhcmVudEl0ZW0ucHJpbWFyeUNhdGVnb3J5ID09PSAnQ291cnNlJykge1xyXG4gICAgICAgICAgYmVsb25nc1RvTWlsZXN0b25lID0gdHJ1ZVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKCFiZWxvbmdzVG9NaWxlc3RvbmUpIGNvbnRpbnVlXHJcblxyXG4gICAgICAvLyBDaGVjayBpZiB0aGlzIGlzIGFuIGFzc2Vzc21lbnQgKHNraXAgb3RoZXIgYXNzZXNzbWVudHMpXHJcbiAgICAgIGNvbnN0IGlzSXRlbUFzc2Vzc21lbnQgPVxyXG4gICAgICAgIGl0ZW0ucHJpbWFyeUNhdGVnb3J5ID09PSAnQ291cnNlIEFzc2Vzc21lbnQnIHx8XHJcbiAgICAgICAgaXRlbS5wcmltYXJ5Q2F0ZWdvcnkgPT09ICdGaW5hbCBBc3Nlc3NtZW50JyB8fFxyXG4gICAgICAgIGl0ZW0ucHJpbWFyeUNhdGVnb3J5ID09PSAnU3RhbmRhbG9uZSBBc3Nlc3NtZW50JyB8fFxyXG4gICAgICAgIGl0ZW0ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi92bmQuc3VuYmlyZC5xdWVzdGlvbnNldCcgfHxcclxuICAgICAgICBpdGVtLm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vcXVpeicgfHxcclxuICAgICAgICAoaXRlbS5uYW1lICYmIGl0ZW0ubmFtZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKCdhc3Nlc3NtZW50JykpXHJcbiAgICAgIFxyXG4gICAgICBpZiAoaXNJdGVtQXNzZXNzbWVudCkgY29udGludWVcclxuXHJcbiAgICAgIC8vIENoZWNrIGlmIHRoaXMgaXMgbWFuZGF0b3J5IGNvbnRlbnRcclxuICAgICAgLy8gQnkgZGVmYXVsdCwgY291cnNlcyBhcmUgbWFuZGF0b3J5IHVubGVzcyBleHBsaWNpdGx5IG1hcmtlZCBvdGhlcndpc2VcclxuICAgICAgY29uc3QgaXNNYW5kYXRvcnkgPSBpdGVtLmlzTWFuZGF0b3J5ICE9PSBmYWxzZSAmJiBcclxuICAgICAgICAoaXRlbS5wcmltYXJ5Q2F0ZWdvcnkgPT09ICdDb3Vyc2UnIHx8IGl0ZW0uaXNNYW5kYXRvcnkgPT09IHRydWUpXHJcblxyXG4gICAgICBpZiAoaXNNYW5kYXRvcnkpIHtcclxuICAgICAgICBtYW5kYXRvcnlDb3VudCsrXHJcbiAgICAgICAgY29uc3QgaXNDb21wbGV0ZWQgPSBcclxuICAgICAgICAgIGl0ZW0uY29tcGxldGlvblN0YXR1cyA9PT0gMiB8fCBcclxuICAgICAgICAgIGl0ZW0uc3RhdHVzID09PSAyIHx8IFxyXG4gICAgICAgICAgaXRlbS5jb21wbGV0aW9uUGVyY2VudGFnZSA+PSAxMDAgfHxcclxuICAgICAgICAgIGl0ZW0ucHJvZ3Jlc3MgPj0gMTAwXHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYgKGlzQ29tcGxldGVkKSB7XHJcbiAgICAgICAgICBjb21wbGV0ZWRNYW5kYXRvcnlDb3VudCsrXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gRGV0ZXJtaW5lIGlmIGFzc2Vzc21lbnQgc2hvdWxkIGJlIGxvY2tlZFxyXG4gICAgY29uc3QgYWxsTWFuZGF0b3J5Q29tcGxldGUgPSBtYW5kYXRvcnlDb3VudCA9PT0gMCB8fCBjb21wbGV0ZWRNYW5kYXRvcnlDb3VudCA+PSBtYW5kYXRvcnlDb3VudFxyXG4gICAgXHJcbiAgICB0aGlzLmhhc2htYXBbYXNzZXNzbWVudElkXS5pc0Fzc2Vzc21lbnRMb2NrZWQgPSAhYWxsTWFuZGF0b3J5Q29tcGxldGVcclxuICAgIHRoaXMuaGFzaG1hcFthc3Nlc3NtZW50SWRdLmFzc2Vzc21lbnRMb2NrTWVzc2FnZSA9ICFhbGxNYW5kYXRvcnlDb21wbGV0ZSA/XHJcbiAgICAgICdUaGlzIGNvbnRlbnQgaXMgbG9ja2VkLiBDb21wbGV0ZSBhbGwgbWFuZGF0b3J5IGl0ZW1zIHRvIHVubG9jayB0aGUgYXNzZXNzbWVudC4nIDogJydcclxuXHJcbiAgICBjb25zb2xlLmxvZyhgQXNzZXNzbWVudCAke2Fzc2Vzc21lbnRJZH0gbG9ja2luZzpgLCB7XHJcbiAgICAgIG1hbmRhdG9yeUNvdW50LFxyXG4gICAgICBjb21wbGV0ZWRNYW5kYXRvcnlDb3VudCxcclxuICAgICAgaXNMb2NrZWQ6ICFhbGxNYW5kYXRvcnlDb21wbGV0ZVxyXG4gICAgfSlcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE1hcmsgYWxsIGNoaWxkcmVuIG9mIGEgbWlsZXN0b25lIGFzIHBhcmVudC1sb2NrZWQgb3IgdW5sb2NrZWRcclxuICAgKi9cclxuICBwcml2YXRlIG1hcmtNaWxlc3RvbmVDaGlsZHJlbkFzUGFyZW50TG9ja2VkKG1pbGVzdG9uZUlkOiBzdHJpbmcsIGlzTG9ja2VkOiBib29sZWFuKTogdm9pZCB7XHJcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyh0aGlzLmhhc2htYXApKSB7XHJcbiAgICAgIGNvbnN0IGl0ZW0gPSB0aGlzLmhhc2htYXBba2V5XVxyXG4gICAgICBcclxuICAgICAgLy8gRGlyZWN0IGNoaWxkcmVuIG9mIG1pbGVzdG9uZVxyXG4gICAgICBpZiAoaXRlbS5wYXJlbnQgPT09IG1pbGVzdG9uZUlkKSB7XHJcbiAgICAgICAgdGhpcy5oYXNobWFwW2tleV0uaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQgPSBpc0xvY2tlZFxyXG4gICAgICAgIFxyXG4gICAgICAgIC8vIEFsc28gbWFyayBuZXN0ZWQgY2hpbGRyZW4gKGUuZy4sIHJlc291cmNlcyBpbnNpZGUgY291cnNlcylcclxuICAgICAgICBpZiAoaXRlbS5jaGlsZHJlbikge1xyXG4gICAgICAgICAgdGhpcy5tYXJrTmVzdGVkQ2hpbGRyZW5Bc1BhcmVudExvY2tlZChrZXksIGlzTG9ja2VkKVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmVjdXJzaXZlbHkgbWFyayBuZXN0ZWQgY2hpbGRyZW4gYXMgcGFyZW50LWxvY2tlZFxyXG4gICAqL1xyXG4gIHByaXZhdGUgbWFya05lc3RlZENoaWxkcmVuQXNQYXJlbnRMb2NrZWQocGFyZW50SWQ6IHN0cmluZywgaXNMb2NrZWQ6IGJvb2xlYW4pOiB2b2lkIHtcclxuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHRoaXMuaGFzaG1hcCkpIHtcclxuICAgICAgY29uc3QgaXRlbSA9IHRoaXMuaGFzaG1hcFtrZXldXHJcbiAgICAgIFxyXG4gICAgICBpZiAoaXRlbS5wYXJlbnQgPT09IHBhcmVudElkKSB7XHJcbiAgICAgICAgdGhpcy5oYXNobWFwW2tleV0uaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQgPSBpc0xvY2tlZFxyXG4gICAgICAgIFxyXG4gICAgICAgIC8vIFJlY3Vyc2UgZm9yIGRlZXBlciBuZXN0aW5nXHJcbiAgICAgICAgaWYgKGl0ZW0uY2hpbGRyZW4pIHtcclxuICAgICAgICAgIHRoaXMubWFya05lc3RlZENoaWxkcmVuQXNQYXJlbnRMb2NrZWQoa2V5LCBpc0xvY2tlZClcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldENhbGN1bGF0aW9uc0Zyb21DaGlsZHJlbihpdGVtOiBOc0NvbnRlbnQuSUNvbnRlbnQpIHtcclxuICAgIGl0ZW1bJ2R1cmF0aW9uJ10gPSBpdGVtLmNoaWxkcmVuLnJlZHVjZSgoc3VtLCBjaGlsZCkgPT4ge1xyXG4gICAgICByZXR1cm4gc3VtICsgTnVtYmVyKGNoaWxkLmR1cmF0aW9uIHx8IDApXHJcbiAgICB9LCAwKVxyXG4gICAgY29uc3QgY29tcGxldGVkSXRlbXMgPSBfLmZpbHRlcihpdGVtLmNoaWxkcmVuLCByID0+IHIuY29tcGxldGlvblN0YXR1cyA9PT0gMiB8fCByLmNvbXBsZXRpb25QZXJjZW50YWdlID09PSAxMDApXHJcbiAgICBjb25zdCB0b3RhbENvdW50ID0gXy50b0ludGVnZXIoXy5nZXQoaXRlbSwgJ2xlYWZOb2Rlc0NvdW50JykpIHx8IDFcclxuICAgIGl0ZW1bJ2NvbXBsZXRpb25QZXJjZW50YWdlJ10gPSBOdW1iZXIoKChjb21wbGV0ZWRJdGVtcy5sZW5ndGggLyB0b3RhbENvdW50KSAqIDEwMCkudG9GaXhlZCgpKVxyXG4gICAgaXRlbVsnY29tcGxldGlvblN0YXR1cyddID0gKGl0ZW0uY29tcGxldGlvblBlcmNlbnRhZ2UgPj0gMTAwKSA/IDIgOiAxXHJcbiAgICByZXR1cm4gaXRlbVxyXG4gIH1cclxuXHJcbiAgZmV0Y2hDb250ZW50SGlzdG9yeVYyKHJlcTogTnNDb250ZW50LklDb250aW51ZUxlYXJuaW5nRGF0YVJlcSk6IE9ic2VydmFibGU8TnNDb250ZW50LklDb250aW51ZUxlYXJuaW5nRGF0YT4ge1xyXG4gICAgcmVxLnJlcXVlc3QuZmllbGRzID0gWydwcm9ncmVzc2RldGFpbHMnXVxyXG5cclxuICAgIGlmIChyZXEucmVxdWVzdC5jb3Vyc2VJZCkge1xyXG4gICAgICBjb25zdCByZXNsdXQ6IGFueSA9IHRoaXMuaHR0cC5wb3N0PE5zQ29udGVudC5JQ29udGludWVMZWFybmluZ0RhdGE+KFxyXG4gICAgICAgIGAke0FQSV9FTkRfUE9JTlRTLkNPTlRFTlRfSElTVE9SWVYyfS8ke3JlcS5yZXF1ZXN0LmNvdXJzZUlkfWAsIHJlcVxyXG4gICAgICApXHJcbiAgICAgIC8vIGRhdGEuc3Vic2NyaWJlKChzdWJzY3JpYmVEYXRhOiBhbnkpID0+IHtcclxuICAgICAgLy8gICAgICAgdGhpcy5wcm9ncmFtQ2hpbGRDb3Vyc2VSZXN1bWVEYXRhLm5leHQoeyByZXN1bWVEYXRhOiBzdWJzY3JpYmVEYXRhLnJlc3VsdC5jb250ZW50TGlzdCwgY291cnNlSWQ6IHJlcS5yZXF1ZXN0LmNvdXJzZUlkIH0pXHJcbiAgICAgIC8vICAgICB9KVxyXG4gICAgICByZXR1cm4gcmVzbHV0XHJcbiAgICB9XHJcbiAgICByZXR1cm4gb2YoKVxyXG5cclxuICB9XHJcblxyXG4gIGRvd29ubG9hZENlcnRpZmljYXRlKGNlcnRJZDogYW55KTogT2JzZXJ2YWJsZTxhbnk+IHtcclxuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PHsgcmVzdWx0OiBhbnkgfT4oXHJcbiAgICAgIEFQSV9FTkRfUE9JTlRTLkNFUlRfRE9XTkxPQUQoY2VydElkKSxcclxuICAgIClcclxuICB9XHJcbiAgZ2V0U2VydmVyRGF0ZSgpIHtcclxuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PHsgcmVzdWx0OiBOc0FwcFRvYy5JUG9zdEFzc2Vzc21lbnRbXSB9PihcclxuICAgICAgQVBJX0VORF9QT0lOVFMuU0VSVkVSX0RBVEUpXHJcbiAgfVxyXG5cclxuICBnZXRGb3JtQnlJZChmb3JtSWQ6IHN0cmluZykge1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQoQVBJX0VORF9QT0lOVFMuR0VUX0ZPUk1fQllJRChmb3JtSWQpKVxyXG4gIH1cclxuXHJcbiAgc3VibWl0Rm9ybShmb3JtRGF0YTogYW55KSB7XHJcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3Q8YW55PihBUElfRU5EX1BPSU5UUy5TVUJNSVRfRk9STSwgZm9ybURhdGEpXHJcbiAgfVxyXG5cclxuICBnZXRGb3JtQnlJZFB1YmxpYyhmb3JtSWQ6IHN0cmluZykge1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQoQVBJX0VORF9QT0lOVFMuR0VUX0ZPUk1fQllJRF9QVUJMSUMoZm9ybUlkKSlcclxuICB9XHJcblxyXG4gIHN1Ym1pdEZvcm1QdWJsaWMoZm9ybURhdGE6IGFueSkge1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0PGFueT4oQVBJX0VORF9QT0lOVFMuU1VCTUlUX0ZPUk1fUFVCTElDLCBmb3JtRGF0YSlcclxuICB9XHJcblxyXG4gIGdldEFwbGxpY2F0aW9uc0J5SWQoZm9ybUlkOiBzdHJpbmcsIGNvbnRleHRJZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxhbnk+IHtcclxuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PGFueT4oQVBJX0VORF9QT0lOVFMuR0VUX0FQUExJQ0FUSU9OU19CWV9JRChmb3JtSWQsIGNvbnRleHRJZCkpXHJcbiAgfVxyXG5cclxuICBzaGFyZUNvbnRlbnQocmVxQm9keTogYW55KSB7XHJcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3Q8YW55PihgJHtBUElfRU5EX1BPSU5UUy5TSEFSRV9DT05URU5UfWAsIHJlcUJvZHkpXHJcbiAgfVxyXG4gIGNoZWNrTW9kdWxlV2lzZURhdGEoY29udGVudDogYW55KSB7XHJcbiAgICBpZiAoY29udGVudCAmJiBjb250ZW50LmNoaWxkcmVuKSB7XHJcbiAgICAgIGNvbnRlbnQuY2hpbGRyZW4uZm9yRWFjaCgoZWxlOiBhbnkpID0+IHtcclxuICAgICAgICBpZiAoZWxlLnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuTU9EVUxFKSB7XHJcbiAgICAgICAgICBsZXQgbW9kdWxlUmVzb3Vyc2VDb3VudCA9IDBcclxuICAgICAgICAgIGxldCBvZmZsaW5lUmVzb3Vyc2VDb3VudCA9IDBcclxuICAgICAgICAgIGVsZS5jaGlsZHJlbi5mb3JFYWNoKChjaGlsZEVsZTogYW55KSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChjaGlsZEVsZS5wcmltYXJ5Q2F0ZWdvcnkgIT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk9GRkxJTkVfU0VTU0lPTikge1xyXG4gICAgICAgICAgICAgIG1vZHVsZVJlc291cnNlQ291bnQgPSBtb2R1bGVSZXNvdXJzZUNvdW50ICsgMVxyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIG9mZmxpbmVSZXNvdXJzZUNvdW50ID0gb2ZmbGluZVJlc291cnNlQ291bnQgKyAxXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0pXHJcbiAgICAgICAgICBlbGVbJ21vZHVsZVJlc291cnNlQ291bnQnXSA9IG1vZHVsZVJlc291cnNlQ291bnRcclxuICAgICAgICAgIGVsZVsnb2ZmbGluZVJlc291cnNlQ291bnQnXSA9IG9mZmxpbmVSZXNvdXJzZUNvdW50XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGlmIChlbGUucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5DT1VSU0UpIHtcclxuICAgICAgICAgICAgdGhpcy5jaGVja01vZHVsZVdpc2VEYXRhKGVsZSlcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH0pXHJcbiAgICB9XHJcbiAgfVxyXG4gIGFzeW5jIGZldGNoQ291cnNlSGVpcmFyY2h5KGNvbnRlbnREYXRhOiBhbnkpIHtcclxuICAgIGlmIChjb250ZW50RGF0YSAmJiBjb250ZW50RGF0YS5jaGlsZHJlbikge1xyXG4gICAgICBmb3IgKGNvbnN0IGVsZSBvZiBjb250ZW50RGF0YS5jaGlsZHJlbikge1xyXG4gICAgICAgIGlmIChlbGUucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRUNvdXJzZUNhdGVnb3J5LkNPVVJTRSkge1xyXG4gICAgICAgICAgYXdhaXQgdGhpcy53aWRnZXRTdmMuZmV0Y2hDb250ZW50KGVsZS5pZGVudGlmaWVyKS50b1Byb21pc2UoKS50aGVuKGFzeW5jIChzdWJFbGU6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoc3ViRWxlLnJlc3VsdCAmJiBzdWJFbGUucmVzdWx0LmNvbnRlbnRcclxuICAgICAgICAgICAgICAmJiBzdWJFbGUucmVzdWx0LmNvbnRlbnQuY2hpbGRyZW4gJiYgc3ViRWxlLnJlc3VsdC5jb250ZW50LmNoaWxkcmVuLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgIGVsZVsnY2hpbGRyZW4nXSA9IHN1YkVsZS5yZXN1bHQuY29udGVudC5jaGlsZHJlblxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9KVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgc2V0VHJhbnNjcmlwdGlvbkRhdGEoZGF0YTogYW55KSB7XHJcbiAgICAvLyAgY29uc29sZS5sb2coJ2RhdGEtLScsIGRhdGEpXHJcbiAgICB0aGlzLnRyYW5zcmlwdGlvbkRhdGFTdWJqZWN0Lm5leHQoZGF0YSk7XHJcbiAgfVxyXG5cclxuICBzZXRBY3RpdmVTdWJ0aXRsZUxhbmd1YWdlKGFjdGl2ZUxhbmc6IGFueSkge1xyXG4gICAgdGhpcy50cmFuc3JpcHRpb25BY3RpdmVMYW5ndWFnZURhdGFPYmplY3QubmV4dChhY3RpdmVMYW5nKVxyXG4gIH1cclxuXHJcblxyXG5cclxuICBhaUdldFJlc291cmNlVnR0RmlsZShyZXNvdXJjZUlEOiBhbnkpIHtcclxuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PGFueT4oYCR7QVBJX0VORF9QT0lOVFMuQUlfUkVTT1VSQ0VfVlRUX0ZJTEV9P3Jlc291cmNlX2lkPSR7cmVzb3VyY2VJRH1gKVxyXG4gIH1cclxuXHJcbiAgcmVhZFByZUVucm9sbG1lbnRSZXNvdXJjZXNTdGF0ZShyZXE6IGFueSkge1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cFxyXG4gICAgICAucG9zdChgJHtBUElfRU5EX1BPSU5UUy5QUkVfRU5ST0xMTUVOVF9TVEFURV9SRUFEfWAsIHJlcSlcclxuICB9XHJcblxyXG4gIGNyZWF0ZUNvbnRlbnRWMihyZXF1ZXN0Qm9keTogYW55KSB7XHJcbiAgICByZXR1cm4gdGhpcy5odHRwXHJcbiAgICAgIC5wb3N0KFxyXG4gICAgICAgIGAke0FQSV9FTkRfUE9JTlRTLkNSRUFURV9SRVNPVVJDRX1gLFxyXG4gICAgICAgIHJlcXVlc3RCb2R5LFxyXG4gICAgICApXHJcbiAgICAgIC5waXBlKFxyXG4gICAgICAgIG1hcCgoZGF0YTogYW55KSA9PiB7XHJcbiAgICAgICAgICByZXR1cm4gZGF0YS5yZXN1bHQuaWRlbnRpZmllclxyXG4gICAgICAgIH0pLFxyXG4gICAgICApXHJcbiAgfVxyXG5cclxuXHJcbiAgdXBsb2FkQXNzaWdubWVudEFuc3dlcihjb250ZW50SWQ6IHN0cmluZywgYmF0Y2hJZDogc3RyaW5nLCBhc3NpZ25tZW50SWQ6IHN0cmluZywgZmlsZTogRmlsZSk6IE9ic2VydmFibGU8YW55PiB7XHJcbiAgICBjb25zdCBmb3JtRGF0YSA9IG5ldyBGb3JtRGF0YSgpO1xyXG4gICAgZm9ybURhdGEuYXBwZW5kKCdmaWxlJywgZmlsZSwgZmlsZS5uYW1lKVxyXG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0KGAke0FQSV9FTkRfUE9JTlRTLlVQTE9BRF9BU1NJR05NRU5UfS8ke2NvbnRlbnRJZH0vJHtiYXRjaElkfS8ke2Fzc2lnbm1lbnRJZH1gLCBmb3JtRGF0YSk7XHJcbiAgfVxyXG5cclxuXHJcbiAgcmVhZENvbnRlbnRWMihpZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxhbnk+IHtcclxuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PGFueT4oXHJcbiAgICAgIGAke0FQSV9FTkRfUE9JTlRTLlJFQURfUkVTT1VSQ0V9cmVhZC8ke2lkfT9tb2RlPWVkaXRgLFxyXG4gICAgKS5waXBlKFxyXG4gICAgICBtYXAoKGRhdGE6IGFueSkgPT4ge1xyXG4gICAgICAgIHJldHVybiBkYXRhLnJlc3VsdC5jb250ZW50XHJcbiAgICAgIH0pXHJcbiAgICApXHJcbiAgfVxyXG5cclxuICB1cGxvYWQoXHJcbiAgICBkYXRhOiBGb3JtRGF0YSxcclxuICAgIGNvbnRlbnREYXRhOiBhbnksXHJcbiAgICBvcHRpb25zPzogYW55LFxyXG4gICk6IE9ic2VydmFibGU8YW55PiB7XHJcblxyXG4gICAgY29uc3QgZmlsZSA9IGRhdGEuZ2V0KCdjb250ZW50JykgYXMgRmlsZVxyXG4gICAgbGV0IGZpbGVOYW1lID0gZmlsZS5uYW1lXHJcbiAgICBpZiAoWydjaGFubmVsLmpzb24nXS5pbmRleE9mKGZpbGVOYW1lKSA8IDApIHtcclxuICAgICAgZmlsZU5hbWUgPSB0aGlzLmFwcGVuZFRvRmlsZW5hbWUoZmlsZU5hbWUpXHJcbiAgICB9XHJcbiAgICBjb25zdCBuZXdGb3JtRGF0YSA9IG5ldyBGb3JtRGF0YSgpXHJcbiAgICBuZXdGb3JtRGF0YS5hcHBlbmQoJ2RhdGEnLCBmaWxlLCBmaWxlTmFtZSlcclxuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdDxhbnk+KFxyXG4gICAgICBgJHtBUElfRU5EX1BPSU5UUy5VUExPQURfRklMRX11cGxvYWQvJHtjb250ZW50RGF0YS5jb250ZW50SWR9YCxcclxuICAgICAgbmV3Rm9ybURhdGEsXHJcbiAgICAgIG9wdGlvbnNcclxuICAgIClcclxuICB9XHJcblxyXG4gIGFwcGVuZFRvRmlsZW5hbWUoZmlsZW5hbWU6IHN0cmluZykge1xyXG4gICAgY29uc3QgdGltZVN0YW1wID0gbmV3IERhdGUoKS5nZXRUaW1lKClcclxuICAgIGNvbnN0IGRvdEluZGV4ID0gZmlsZW5hbWUubGFzdEluZGV4T2YoJy4nKVxyXG4gICAgaWYgKGRvdEluZGV4ID09PSAtMSkge1xyXG4gICAgICByZXR1cm4gZmlsZW5hbWUgKyB0aW1lU3RhbXBcclxuICAgIH1cclxuICAgIHJldHVybiBmaWxlbmFtZS5zdWJzdHJpbmcoMCwgZG90SW5kZXgpICsgdGltZVN0YW1wICsgZmlsZW5hbWUuc3Vic3RyaW5nKGRvdEluZGV4KVxyXG4gIH1cclxuXHJcbiAgdXBkYXRlQ29udGVudFdpdGhGZXdGaWVsZHMocmVxdWVzdEJvZHk6IGFueSwgaWRlbnRpZmllcjogc3RyaW5nKTogT2JzZXJ2YWJsZTxhbnk+IHtcclxuICAgIHJldHVybiB0aGlzLmh0dHAucGF0Y2g8YW55PihcclxuICAgICAgYCR7QVBJX0VORF9QT0lOVFMuVVBEQVRFX1JFU09VUkNFfS8ke2lkZW50aWZpZXJ9YCxcclxuICAgICAgcmVxdWVzdEJvZHksXHJcbiAgICApXHJcbiAgfVxyXG5cclxuICBzZWFyY2hBc3NpZ25tZW50cyhyZXF1ZXN0OiBhbnkpOiBPYnNlcnZhYmxlPGFueT4ge1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0KEFQSV9FTkRfUE9JTlRTLlNFQVJDSCwgcmVxdWVzdClcclxuICB9XHJcblxyXG4gIHN1Ym1pdERyYWZ0QXNzaWdubWVudChyZXF1ZXN0OiBhbnkpOiBPYnNlcnZhYmxlPGFueT4ge1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wdXQoQVBJX0VORF9QT0lOVFMuU1VCTUlUX0RSQUZUX0FTU0lHTk1FTlQsIHJlcXVlc3QpXHJcbiAgfVxyXG5cclxuICBzdWJtaXRBc3NpZ25tZW50KHJlcXVlc3Q6IGFueSk6IE9ic2VydmFibGU8YW55PiB7XHJcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3QoQVBJX0VORF9QT0lOVFMuU1VCTUlUX0FTU0lHTk1FTlQsIHJlcXVlc3QpXHJcbiAgfVxyXG5cclxuICBub3RpZnlBc3NpZ25tZW50U3VibWlzc2lvbihwYXlsb2FkOiBhbnkpOiBPYnNlcnZhYmxlPGFueT4ge1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0KEFQSV9FTkRfUE9JTlRTLk5PVElGWV9BU1NJR05NRU5UX1NVQk1JU1NJT04sIHBheWxvYWQpXHJcbiAgfVxyXG5cclxuICBnZXRBc3NpZ25tZW50U3RhdHVzKHJlcXVlc3Q6IGFueSk6IE9ic2VydmFibGU8YW55PiB7XHJcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3QoYCR7QVBJX0VORF9QT0lOVFMuQVNTSUdOTUVOVF9TVEFUVVN9YCwgcmVxdWVzdClcclxuICB9XHJcblxyXG4gIHJlYWRBc3NpZ25tZW50RmlsZShjb250ZW50SWQ6IHN0cmluZywgYmF0Y2hJZDogc3RyaW5nLCBhc3NpZ25tZW50SWQ6IHN0cmluZywgZmlsZU5hbWU6IHN0cmluZyk6IE9ic2VydmFibGU8YW55PiB7XHJcbiAgICAvLyBQcm9wZXJseSBlbmNvZGUgdGhlIHBhcmFtZXRlcnMgdG8gYXZvaWQgbWFsZm9ybWVkIHJlcXVlc3QgZXJyb3JzXHJcbiAgICBjb25zdCBlbmNvZGVkUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh7XHJcbiAgICAgIGNvbnRlbnRJZDogY29udGVudElkIHx8ICcnLFxyXG4gICAgICBiYXRjaElkOiBiYXRjaElkIHx8ICcnLFxyXG4gICAgICBmb3JtSWQ6IGFzc2lnbm1lbnRJZCB8fCAnJyxcclxuICAgICAgZmlsZU5hbWU6IGZpbGVOYW1lIHx8ICcnXHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gdGhpcy5odHRwLmdldChgJHtBUElfRU5EX1BPSU5UUy5SRUFEX0FTU0lHTk1FTlR9PyR7ZW5jb2RlZFBhcmFtcy50b1N0cmluZygpfWAsIHtcclxuICAgICAgcmVzcG9uc2VUeXBlOiAnYmxvYicsXHJcbiAgICAgIGhlYWRlcnM6IHtcclxuICAgICAgICAnQWNjZXB0JzogJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSwgYXBwbGljYXRpb24vcGRmLCBhcHBsaWNhdGlvbi9tc3dvcmQsIGFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC53b3JkcHJvY2Vzc2luZ21sLmRvY3VtZW50J1xyXG4gICAgICB9XHJcbiAgICB9KS5waXBlKFxyXG4gICAgICBjYXRjaEVycm9yKChlcnJvcjogYW55KSA9PiB7XHJcbiAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gZXJyb3IpO1xyXG4gICAgICB9KVxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdlbmVyYXRlIG1pbGVzdG9uZSBhY2hpZXZlbWVudFxyXG4gICAqIEBwYXJhbSB1c2VySWQgVXNlciBJRFxyXG4gICAqIEBwYXJhbSBjb3Vyc2VJZCBDb3Vyc2UgaWRlbnRpZmllclxyXG4gICAqIEBwYXJhbSBiYXRjaElkIEJhdGNoIElEXHJcbiAgICogQHBhcmFtIG1pbGVzdG9uZUlkIE1pbGVzdG9uZSBpZGVudGlmaWVyIChlLmcuLCAnbTEnLCAnbTInKVxyXG4gICAqL1xyXG4gIGdlbmVyYXRlTWlsZXN0b25lQWNoaWV2ZW1lbnQodXNlcklkOiBzdHJpbmcsIGNvdXJzZUlkOiBzdHJpbmcsIGJhdGNoSWQ6IHN0cmluZywgbWlsZXN0b25lSWQ6IHN0cmluZyk6IE9ic2VydmFibGU8YW55PiB7XHJcbiAgICBjb25zdCBhcGlVcmwgPSAnL2FwaXMvcHJveGllcy92OC9hY2hpZXZlbWVudC9keW5hbWljL3YxL2dlbmVyYXRlJ1xyXG4gICAgY29uc3QgcmVxdWVzdCA9IHtcclxuICAgICAgcmVxdWVzdDoge1xyXG4gICAgICAgIHVzZXJJZCxcclxuICAgICAgICBjb3Vyc2VJZCxcclxuICAgICAgICBiYXRjaElkLFxyXG4gICAgICAgIG1pbGVzdG9uZUlkXHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdChhcGlVcmwsIHJlcXVlc3QpXHJcbiAgfVxyXG5cclxufVxyXG4iXX0=