@sunbird-cb/toc 0.0.9 → 0.0.11

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 (495) 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 +272 -248
  28. package/esm2022/lib/_collection/_common/content-toc/app-toc-content-card-v2/app-toc-content-card-v2.component.mjs +1202 -1148
  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 +2938 -2907
  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 +333 -313
  143. package/esm2022/lib/services/app-toc.service.mjs +1647 -1613
  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 +599 -590
  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 +73 -71
  164. package/esm2022/sunbird-cb-toc.mjs +4 -4
  165. package/fesm2022/sunbird-cb-toc.mjs +24942 -24771
  166. package/fesm2022/sunbird-cb-toc.mjs.map +1 -1
  167. package/index.d.ts +6 -5
  168. package/lib/_collection/_common/attendance-card/attendance-card.component.d.ts +17 -16
  169. package/lib/_collection/_common/attendance-card/attendance-card.component.d.ts.map +1 -0
  170. package/lib/_collection/_common/attendance-card/attendance-card.module.d.ts +32 -31
  171. package/lib/_collection/_common/attendance-card/attendance-card.module.d.ts.map +1 -0
  172. package/lib/_collection/_common/attendance-helper/attendance-helper.component.d.ts +16 -15
  173. package/lib/_collection/_common/attendance-helper/attendance-helper.component.d.ts.map +1 -0
  174. package/lib/_collection/_common/attendance-helper/attendance-helper.module.d.ts +21 -20
  175. package/lib/_collection/_common/attendance-helper/attendance-helper.module.d.ts.map +1 -0
  176. package/lib/_collection/_common/avatar-photo/avatar-photo.component.d.ts +23 -22
  177. package/lib/_collection/_common/avatar-photo/avatar-photo.component.d.ts.map +1 -0
  178. package/lib/_collection/_common/avatar-photo/avatar-photo.module.d.ts +16 -15
  179. package/lib/_collection/_common/avatar-photo/avatar-photo.module.d.ts.map +1 -0
  180. package/lib/_collection/_common/certificate-dialog/certificate-dialog.component.d.ts +23 -22
  181. package/lib/_collection/_common/certificate-dialog/certificate-dialog.component.d.ts.map +1 -0
  182. package/lib/_collection/_common/certificate-dialog/certificate-dialog.module.d.ts +23 -22
  183. package/lib/_collection/_common/certificate-dialog/certificate-dialog.module.d.ts.map +1 -0
  184. package/lib/_collection/_common/certificate-dialog/svg-to-pdf.component.d.ts +10 -9
  185. package/lib/_collection/_common/certificate-dialog/svg-to-pdf.component.d.ts.map +1 -0
  186. package/lib/_collection/_common/confirm-dialog/confirm-dialog.component.d.ts +12 -11
  187. package/lib/_collection/_common/confirm-dialog/confirm-dialog.component.d.ts.map +1 -0
  188. package/lib/_collection/_common/confirm-dialog/confirm-dialog.module.d.ts +13 -12
  189. package/lib/_collection/_common/confirm-dialog/confirm-dialog.module.d.ts.map +1 -0
  190. package/lib/_collection/_common/connection-hover-card/connection-hover-card.component.d.ts +19 -18
  191. package/lib/_collection/_common/connection-hover-card/connection-hover-card.component.d.ts.map +1 -0
  192. package/lib/_collection/_common/connection-hover-card/connection-hover.module.d.ts +15 -14
  193. package/lib/_collection/_common/connection-hover-card/connection-hover.module.d.ts.map +1 -0
  194. package/lib/_collection/_common/connection-hover-card/connection-hover.servive.d.ts +12 -11
  195. package/lib/_collection/_common/connection-hover-card/connection-hover.servive.d.ts.map +1 -0
  196. package/lib/_collection/_common/connection-name/connection-name.component.d.ts +18 -17
  197. package/lib/_collection/_common/connection-name/connection-name.component.d.ts.map +1 -0
  198. package/lib/_collection/_common/connection-name/connection-name.module.d.ts +15 -14
  199. package/lib/_collection/_common/connection-name/connection-name.module.d.ts.map +1 -0
  200. package/lib/_collection/_common/connection-name/profile-v2.model.d.ts +200 -199
  201. package/lib/_collection/_common/connection-name/profile-v2.model.d.ts.map +1 -0
  202. package/lib/_collection/_common/content-progress/content-progress.component.d.ts +17 -16
  203. package/lib/_collection/_common/content-progress/content-progress.component.d.ts.map +1 -0
  204. package/lib/_collection/_common/content-progress/content-progress.module.d.ts +11 -10
  205. package/lib/_collection/_common/content-progress/content-progress.module.d.ts.map +1 -0
  206. package/lib/_collection/_common/content-rating-v2-dialog/content-rating-v2-dialog.component.d.ts +39 -38
  207. package/lib/_collection/_common/content-rating-v2-dialog/content-rating-v2-dialog.component.d.ts.map +1 -0
  208. package/lib/_collection/_common/content-rating-v2-dialog/content-rating-v2-dialog.module.d.ts +20 -19
  209. package/lib/_collection/_common/content-rating-v2-dialog/content-rating-v2-dialog.module.d.ts.map +1 -0
  210. package/lib/_collection/_common/content-toc/ai-tutor-confirm-popup/ai-tutor-confirm-popup.component.d.ts +12 -11
  211. package/lib/_collection/_common/content-toc/ai-tutor-confirm-popup/ai-tutor-confirm-popup.component.d.ts.map +1 -0
  212. package/lib/_collection/_common/content-toc/app-toc-about/app-toc-about.component.d.ts +184 -183
  213. package/lib/_collection/_common/content-toc/app-toc-about/app-toc-about.component.d.ts.map +1 -0
  214. package/lib/_collection/_common/content-toc/app-toc-assignment-viewer/app-toc-assignment-viewer.component.d.ts +42 -41
  215. package/lib/_collection/_common/content-toc/app-toc-assignment-viewer/app-toc-assignment-viewer.component.d.ts.map +1 -0
  216. package/lib/_collection/_common/content-toc/app-toc-assignment-viewerV2/app-toc-assignment-viewerV2.component.d.ts +55 -54
  217. package/lib/_collection/_common/content-toc/app-toc-assignment-viewerV2/app-toc-assignment-viewerV2.component.d.ts.map +1 -0
  218. package/lib/_collection/_common/content-toc/app-toc-batch-assignments/app-toc-batch-assignments.component.d.ts +48 -47
  219. package/lib/_collection/_common/content-toc/app-toc-batch-assignments/app-toc-batch-assignments.component.d.ts.map +1 -0
  220. package/lib/_collection/_common/content-toc/app-toc-content/app-toc-content.component.d.ts +57 -49
  221. package/lib/_collection/_common/content-toc/app-toc-content/app-toc-content.component.d.ts.map +1 -0
  222. package/lib/_collection/_common/content-toc/app-toc-content-card-v2/app-toc-content-card-v2.component.d.ts +186 -171
  223. package/lib/_collection/_common/content-toc/app-toc-content-card-v2/app-toc-content-card-v2.component.d.ts.map +1 -0
  224. package/lib/_collection/_common/content-toc/app-toc-content-card-v2-skeleton/app-toc-content-card-v2-skeleton.component.d.ts +9 -8
  225. package/lib/_collection/_common/content-toc/app-toc-content-card-v2-skeleton/app-toc-content-card-v2-skeleton.component.d.ts.map +1 -0
  226. package/lib/_collection/_common/content-toc/app-toc-reference-notes/app-toc-reference-notes.component.d.ts +17 -16
  227. package/lib/_collection/_common/content-toc/app-toc-reference-notes/app-toc-reference-notes.component.d.ts.map +1 -0
  228. package/lib/_collection/_common/content-toc/app-toc-session-card-new/app-toc-session-card-new.component.d.ts +41 -40
  229. package/lib/_collection/_common/content-toc/app-toc-session-card-new/app-toc-session-card-new.component.d.ts.map +1 -0
  230. package/lib/_collection/_common/content-toc/app-toc-sessions-new/app-toc-sessions-new.component.d.ts +22 -21
  231. package/lib/_collection/_common/content-toc/app-toc-sessions-new/app-toc-sessions-new.component.d.ts.map +1 -0
  232. package/lib/_collection/_common/content-toc/app-toc-teachers-notes/app-toc-teachers-notes.component.d.ts +46 -45
  233. package/lib/_collection/_common/content-toc/app-toc-teachers-notes/app-toc-teachers-notes.component.d.ts.map +1 -0
  234. package/lib/_collection/_common/content-toc/content-services/handle-claim.service.d.ts +11 -10
  235. package/lib/_collection/_common/content-toc/content-services/handle-claim.service.d.ts.map +1 -0
  236. package/lib/_collection/_common/content-toc/content-services/review-component-data.service.d.ts +11 -10
  237. package/lib/_collection/_common/content-toc/content-services/review-component-data.service.d.ts.map +1 -0
  238. package/lib/_collection/_common/content-toc/content-toc.component.d.ts +129 -128
  239. package/lib/_collection/_common/content-toc/content-toc.component.d.ts.map +1 -0
  240. package/lib/_collection/_common/content-toc/content-toc.module.d.ts +52 -51
  241. package/lib/_collection/_common/content-toc/content-toc.module.d.ts.map +1 -0
  242. package/lib/_collection/_common/content-toc/karma-points/karma-points.component.d.ts +30 -29
  243. package/lib/_collection/_common/content-toc/karma-points/karma-points.component.d.ts.map +1 -0
  244. package/lib/_collection/_common/content-toc/karma-points/karma-points.module.d.ts +10 -9
  245. package/lib/_collection/_common/content-toc/karma-points/karma-points.module.d.ts.map +1 -0
  246. package/lib/_collection/_common/content-toc/pipes/replace-nbsp.pipe.d.ts +8 -7
  247. package/lib/_collection/_common/content-toc/pipes/replace-nbsp.pipe.d.ts.map +1 -0
  248. package/lib/_collection/_common/content-toc/pipes/truncate.pipe.d.ts +8 -7
  249. package/lib/_collection/_common/content-toc/pipes/truncate.pipe.d.ts.map +1 -0
  250. package/lib/_collection/_common/content-toc/reviews-content/reviews-content.component.d.ts +29 -28
  251. package/lib/_collection/_common/content-toc/reviews-content/reviews-content.component.d.ts.map +1 -0
  252. package/lib/_collection/_common/content-toc/samuhik-charcha-content/samuhik-charcha-content/samuhik-charcha-content.component.d.ts +25 -24
  253. package/lib/_collection/_common/content-toc/samuhik-charcha-content/samuhik-charcha-content/samuhik-charcha-content.component.d.ts.map +1 -0
  254. package/lib/_collection/_common/display-content-type/display-content-type.component.d.ts +15 -14
  255. package/lib/_collection/_common/display-content-type/display-content-type.component.d.ts.map +1 -0
  256. package/lib/_collection/_common/display-content-type/display-content-type.module.d.ts +10 -9
  257. package/lib/_collection/_common/display-content-type/display-content-type.module.d.ts.map +1 -0
  258. package/lib/_collection/_common/display-content-type-icon/display-content-type-icon.component.d.ts +13 -12
  259. package/lib/_collection/_common/display-content-type-icon/display-content-type-icon.component.d.ts.map +1 -0
  260. package/lib/_collection/_common/display-content-type-icon/display-content-type-icon.module.d.ts +11 -10
  261. package/lib/_collection/_common/display-content-type-icon/display-content-type-icon.module.d.ts.map +1 -0
  262. package/lib/_collection/_common/mark-as-complete/mark-as-complete.component.d.ts +23 -22
  263. package/lib/_collection/_common/mark-as-complete/mark-as-complete.component.d.ts.map +1 -0
  264. package/lib/_collection/_common/mark-as-complete/mark-as-complete.model.d.ts +9 -8
  265. package/lib/_collection/_common/mark-as-complete/mark-as-complete.model.d.ts.map +1 -0
  266. package/lib/_collection/_common/mark-as-complete/mark-as-complete.module.d.ts +19 -18
  267. package/lib/_collection/_common/mark-as-complete/mark-as-complete.module.d.ts.map +1 -0
  268. package/lib/_collection/_common/pipe-content-route/pipe-content-route.module.d.ts +9 -8
  269. package/lib/_collection/_common/pipe-content-route/pipe-content-route.module.d.ts.map +1 -0
  270. package/lib/_collection/_common/pipe-content-route/pipe-content-route.pipe.d.ts +16 -15
  271. package/lib/_collection/_common/pipe-content-route/pipe-content-route.pipe.d.ts.map +1 -0
  272. package/lib/_collection/_common/player-brief/player-brief.component.d.ts +36 -35
  273. package/lib/_collection/_common/player-brief/player-brief.component.d.ts.map +1 -0
  274. package/lib/_collection/_common/player-brief/player-brief.module.d.ts +20 -19
  275. package/lib/_collection/_common/player-brief/player-brief.module.d.ts.map +1 -0
  276. package/lib/_collection/_common/rating-summary/rating-summary.component.d.ts +15 -14
  277. package/lib/_collection/_common/rating-summary/rating-summary.component.d.ts.map +1 -0
  278. package/lib/_collection/_common/rating-summary/rating-summary.module.d.ts +14 -13
  279. package/lib/_collection/_common/rating-summary/rating-summary.module.d.ts.map +1 -0
  280. package/lib/_collection/_common/skeleton-loader/skeleton-loader.component.d.ts +12 -11
  281. package/lib/_collection/_common/skeleton-loader/skeleton-loader.component.d.ts.map +1 -0
  282. package/lib/_collection/_common/skeleton-loader/skeleton-loader.module.d.ts +12 -11
  283. package/lib/_collection/_common/skeleton-loader/skeleton-loader.module.d.ts.map +1 -0
  284. package/lib/_collection/_common/tips-for-learner/tips-for-learner-card/tips-for-learner-card.component.d.ts +16 -15
  285. package/lib/_collection/_common/tips-for-learner/tips-for-learner-card/tips-for-learner-card.component.d.ts.map +1 -0
  286. package/lib/_collection/_common/tips-for-learner/tips-for-learner.module.d.ts +11 -10
  287. package/lib/_collection/_common/tips-for-learner/tips-for-learner.module.d.ts.map +1 -0
  288. package/lib/_collection/_common/toc-kpi-values/toc-kpi-values.component.d.ts +17 -16
  289. package/lib/_collection/_common/toc-kpi-values/toc-kpi-values.component.d.ts.map +1 -0
  290. package/lib/_collection/_common/toc-kpi-values/toc-kpi-values.module.d.ts +12 -11
  291. package/lib/_collection/_common/toc-kpi-values/toc-kpi-values.module.d.ts.map +1 -0
  292. package/lib/_collection/_common/user-autocomplete/user-autocomplete.component.d.ts +35 -34
  293. package/lib/_collection/_common/user-autocomplete/user-autocomplete.component.d.ts.map +1 -0
  294. package/lib/_collection/_common/user-autocomplete/user-autocomplete.model.d.ts +18 -17
  295. package/lib/_collection/_common/user-autocomplete/user-autocomplete.model.d.ts.map +1 -0
  296. package/lib/_collection/_common/user-autocomplete/user-autocomplete.module.d.ts +16 -15
  297. package/lib/_collection/_common/user-autocomplete/user-autocomplete.module.d.ts.map +1 -0
  298. package/lib/_collection/_common/user-autocomplete/user-autocomplete.service.d.ts +16 -15
  299. package/lib/_collection/_common/user-autocomplete/user-autocomplete.service.d.ts.map +1 -0
  300. package/lib/_collection/_common/user-content-rating/user-content-rating.component.d.ts +22 -21
  301. package/lib/_collection/_common/user-content-rating/user-content-rating.component.d.ts.map +1 -0
  302. package/lib/_collection/_common/user-content-rating/user-content-rating.module.d.ts +13 -12
  303. package/lib/_collection/_common/user-content-rating/user-content-rating.module.d.ts.map +1 -0
  304. package/lib/_collection/_common/user-image/user-image.component.d.ts +22 -21
  305. package/lib/_collection/_common/user-image/user-image.component.d.ts.map +1 -0
  306. package/lib/_collection/_common/user-image/user-image.module.d.ts +10 -9
  307. package/lib/_collection/_common/user-image/user-image.module.d.ts.map +1 -0
  308. package/lib/_collection/btn-page-back/btn-page-back.component.d.ts +48 -47
  309. package/lib/_collection/btn-page-back/btn-page-back.component.d.ts.map +1 -0
  310. package/lib/_collection/btn-page-back/btn-page-back.module.d.ts +15 -14
  311. package/lib/_collection/btn-page-back/btn-page-back.module.d.ts.map +1 -0
  312. package/lib/_collection/btn-page-back/btn-page-back.service.d.ts +23 -22
  313. package/lib/_collection/btn-page-back/btn-page-back.service.d.ts.map +1 -0
  314. package/lib/_collection/card-rating-comment/card-rating-comment.component.d.ts +20 -19
  315. package/lib/_collection/card-rating-comment/card-rating-comment.component.d.ts.map +1 -0
  316. package/lib/_collection/card-rating-comment/card-rating-comment.module.d.ts +16 -15
  317. package/lib/_collection/card-rating-comment/card-rating-comment.module.d.ts.map +1 -0
  318. package/lib/_collection/sliders-dynamic/sliders-dynamic.component.d.ts +26 -25
  319. package/lib/_collection/sliders-dynamic/sliders-dynamic.component.d.ts.map +1 -0
  320. package/lib/_collection/sliders-dynamic/sliders-dynamic.model.d.ts +22 -21
  321. package/lib/_collection/sliders-dynamic/sliders-dynamic.model.d.ts.map +1 -0
  322. package/lib/_collection/sliders-dynamic/sliders-dynamic.module.d.ts +19 -18
  323. package/lib/_collection/sliders-dynamic/sliders-dynamic.module.d.ts.map +1 -0
  324. package/lib/_collection-api.d.ts +35 -34
  325. package/lib/_collection-api.d.ts.map +1 -0
  326. package/lib/_constants/widget-content.constants.d.ts +8 -7
  327. package/lib/_constants/widget-content.constants.d.ts.map +1 -0
  328. package/lib/_directives/tooltip.directive.d.ts +18 -17
  329. package/lib/_directives/tooltip.directive.d.ts.map +1 -0
  330. package/lib/_models/common.model.d.ts +4 -3
  331. package/lib/_models/common.model.d.ts.map +1 -0
  332. package/lib/_models/error.model.d.ts +6 -5
  333. package/lib/_models/error.model.d.ts.map +1 -0
  334. package/lib/_pipes/highlight.pipe.d.ts +11 -10
  335. package/lib/_pipes/highlight.pipe.d.ts.map +1 -0
  336. package/lib/_services/rating.service.d.ts +19 -18
  337. package/lib/_services/rating.service.d.ts.map +1 -0
  338. package/lib/_services/samuhik-charcha.service.d.ts +14 -13
  339. package/lib/_services/samuhik-charcha.service.d.ts.map +1 -0
  340. package/lib/_services/viewer-route-util.d.ts +9 -8
  341. package/lib/_services/viewer-route-util.d.ts.map +1 -0
  342. package/lib/_services/widget-content.model.d.ts +516 -515
  343. package/lib/_services/widget-content.model.d.ts.map +1 -0
  344. package/lib/_services/widget-content.service.d.ts +102 -101
  345. package/lib/_services/widget-content.service.d.ts.map +1 -0
  346. package/lib/_shared/translate-loader.factory.d.ts +8 -7
  347. package/lib/_shared/translate-loader.factory.d.ts.map +1 -0
  348. package/lib/app-toc-lib.module.d.ts +89 -88
  349. package/lib/app-toc-lib.module.d.ts.map +1 -0
  350. package/lib/collection.config.d.ts +160 -159
  351. package/lib/collection.config.d.ts.map +1 -0
  352. package/lib/components/app-toc-analytics-tiles/app-toc-analytics-tiles.component.d.ts +18 -17
  353. package/lib/components/app-toc-analytics-tiles/app-toc-analytics-tiles.component.d.ts.map +1 -0
  354. package/lib/components/app-toc-banner/app-toc-banner.component.d.ts +226 -225
  355. package/lib/components/app-toc-banner/app-toc-banner.component.d.ts.map +1 -0
  356. package/lib/components/app-toc-cios-home/app-toc-cios-home.component.d.ts +79 -78
  357. package/lib/components/app-toc-cios-home/app-toc-cios-home.component.d.ts.map +1 -0
  358. package/lib/components/app-toc-cios-home/consent-dialog.component.d.ts +23 -22
  359. package/lib/components/app-toc-cios-home/consent-dialog.component.d.ts.map +1 -0
  360. package/lib/components/app-toc-cohorts/app-toc-cohorts.component.d.ts +32 -31
  361. package/lib/components/app-toc-cohorts/app-toc-cohorts.component.d.ts.map +1 -0
  362. package/lib/components/app-toc-content-card/app-toc-content-card.component.d.ts +48 -47
  363. package/lib/components/app-toc-content-card/app-toc-content-card.component.d.ts.map +1 -0
  364. package/lib/components/app-toc-dialog-intro-video/app-toc-dialog-intro-video.component.d.ts +15 -14
  365. package/lib/components/app-toc-dialog-intro-video/app-toc-dialog-intro-video.component.d.ts.map +1 -0
  366. package/lib/components/app-toc-discussion/app-toc-discussion.component.d.ts +22 -21
  367. package/lib/components/app-toc-discussion/app-toc-discussion.component.d.ts.map +1 -0
  368. package/lib/components/app-toc-home/app-toc-home.component.d.ts +315 -314
  369. package/lib/components/app-toc-home/app-toc-home.component.d.ts.map +1 -0
  370. package/lib/components/app-toc-home-v2/app-toc-home-v2.component.d.ts +415 -408
  371. package/lib/components/app-toc-home-v2/app-toc-home-v2.component.d.ts.map +1 -0
  372. package/lib/components/app-toc-overview/app-toc-overview.component.d.ts +48 -47
  373. package/lib/components/app-toc-overview/app-toc-overview.component.d.ts.map +1 -0
  374. package/lib/components/app-toc-session-card/app-toc-session-card.component.d.ts +23 -22
  375. package/lib/components/app-toc-session-card/app-toc-session-card.component.d.ts.map +1 -0
  376. package/lib/components/app-toc-sessions/app-toc-sessions.component.d.ts +15 -14
  377. package/lib/components/app-toc-sessions/app-toc-sessions.component.d.ts.map +1 -0
  378. package/lib/components/app-toc-single-page/app-toc-single-page.component.d.ts +150 -149
  379. package/lib/components/app-toc-single-page/app-toc-single-page.component.d.ts.map +1 -0
  380. package/lib/components/completion-survey-form/completion-survey-form.component.d.ts +43 -42
  381. package/lib/components/completion-survey-form/completion-survey-form.component.d.ts.map +1 -0
  382. package/lib/components/create-batch-dialog/create-batch-dialog.component.d.ts +28 -27
  383. package/lib/components/create-batch-dialog/create-batch-dialog.component.d.ts.map +1 -0
  384. package/lib/components/enroll-language-dialogue/enroll-language-dialogue.component.d.ts +16 -15
  385. package/lib/components/enroll-language-dialogue/enroll-language-dialogue.component.d.ts.map +1 -0
  386. package/lib/components/enroll-profile-form/enroll-profile-form.component.d.ts +196 -195
  387. package/lib/components/enroll-profile-form/enroll-profile-form.component.d.ts.map +1 -0
  388. package/lib/components/enroll-questionnaire/enroll-questionnaire.component.d.ts +45 -44
  389. package/lib/components/enroll-questionnaire/enroll-questionnaire.component.d.ts.map +1 -0
  390. package/lib/components/knowledge-artifact-details/knowledge-artifact-details.component.d.ts +55 -54
  391. package/lib/components/knowledge-artifact-details/knowledge-artifact-details.component.d.ts.map +1 -0
  392. package/lib/components/non-relevent-feedback-dialog/non-relevent-feedback-dialog.component.d.ts +19 -18
  393. package/lib/components/non-relevent-feedback-dialog/non-relevent-feedback-dialog.component.d.ts.map +1 -0
  394. package/lib/components/public-survey-form/public-survey-form.component.d.ts +44 -43
  395. package/lib/components/public-survey-form/public-survey-form.component.d.ts.map +1 -0
  396. package/lib/components/survey-form-question/survey-form-question.component.d.ts +21 -20
  397. package/lib/components/survey-form-question/survey-form-question.component.d.ts.map +1 -0
  398. package/lib/components/survey-form-section/survey-form-section.component.d.ts +14 -13
  399. package/lib/components/survey-form-section/survey-form-section.component.d.ts.map +1 -0
  400. package/lib/models/app-toc-analytics.model.d.ts +153 -152
  401. package/lib/models/app-toc-analytics.model.d.ts.map +1 -0
  402. package/lib/models/app-toc.model.d.ts +85 -84
  403. package/lib/models/app-toc.model.d.ts.map +1 -0
  404. package/lib/models/auto-complete.model.d.ts +28 -27
  405. package/lib/models/auto-complete.model.d.ts.map +1 -0
  406. package/lib/models/card-content.model.d.ts +20 -19
  407. package/lib/models/card-content.model.d.ts.map +1 -0
  408. package/lib/models/content-strip-with-tabs.model.d.ts +45 -44
  409. package/lib/models/content-strip-with-tabs.model.d.ts.map +1 -0
  410. package/lib/models/discussion-forum.model.d.ts +41 -40
  411. package/lib/models/discussion-forum.model.d.ts.map +1 -0
  412. package/lib/models/goal.model.d.ts +23 -22
  413. package/lib/models/goal.model.d.ts.map +1 -0
  414. package/lib/models/meta-tag.model.d.ts +7 -6
  415. package/lib/models/meta-tag.model.d.ts.map +1 -0
  416. package/lib/models/playlist.model.d.ts +24 -23
  417. package/lib/models/playlist.model.d.ts.map +1 -0
  418. package/lib/models/profile-revamp.model.d.ts +15 -14
  419. package/lib/models/profile-revamp.model.d.ts.map +1 -0
  420. package/lib/models/rating.model.d.ts +18 -17
  421. package/lib/models/rating.model.d.ts.map +1 -0
  422. package/lib/models/user-profile.model.d.ts +38 -37
  423. package/lib/models/user-profile.model.d.ts.map +1 -0
  424. package/lib/resolvers/app-toc-cios-resolver.service.d.ts +13 -12
  425. package/lib/resolvers/app-toc-cios-resolver.service.d.ts.map +1 -0
  426. package/lib/resolvers/app-toc-cios-user-enroll-resolver.service.d.ts +13 -12
  427. package/lib/resolvers/app-toc-cios-user-enroll-resolver.service.d.ts.map +1 -0
  428. package/lib/resolvers/app-toc-content-read-resolver.service.d.ts +17 -16
  429. package/lib/resolvers/app-toc-content-read-resolver.service.d.ts.map +1 -0
  430. package/lib/resolvers/app-toc-ext-public-resolver.service.d.ts +13 -12
  431. package/lib/resolvers/app-toc-ext-public-resolver.service.d.ts.map +1 -0
  432. package/lib/resolvers/app-toc-resolver.service.d.ts +17 -16
  433. package/lib/resolvers/app-toc-resolver.service.d.ts.map +1 -0
  434. package/lib/resolvers/config-resolver.service.d.ts +12 -11
  435. package/lib/resolvers/config-resolver.service.d.ts.map +1 -0
  436. package/lib/resolvers/profile-resolver.service.d.ts +12 -11
  437. package/lib/resolvers/profile-resolver.service.d.ts.map +1 -0
  438. package/lib/resolvers/restricted-features-resolver.service.d.ts +12 -11
  439. package/lib/resolvers/restricted-features-resolver.service.d.ts.map +1 -0
  440. package/lib/routes/app-toc-home/app-toc-home.component.d.ts +20 -19
  441. package/lib/routes/app-toc-home/app-toc-home.component.d.ts.map +1 -0
  442. package/lib/routes/app-toc-home/app-toc-home.directive.d.ts +9 -8
  443. package/lib/routes/app-toc-home/app-toc-home.directive.d.ts.map +1 -0
  444. package/lib/routes/app-toc-home/app-toc-home.service.d.ts +9 -8
  445. package/lib/routes/app-toc-home/app-toc-home.service.d.ts.map +1 -0
  446. package/lib/services/access-control.service.d.ts +30 -29
  447. package/lib/services/access-control.service.d.ts.map +1 -0
  448. package/lib/services/action.service.d.ts +10 -9
  449. package/lib/services/action.service.d.ts.map +1 -0
  450. package/lib/services/app-toc-v2.service.d.ts +17 -16
  451. package/lib/services/app-toc-v2.service.d.ts.map +1 -0
  452. package/lib/services/app-toc.service.d.ts +241 -235
  453. package/lib/services/app-toc.service.d.ts.map +1 -0
  454. package/lib/services/certificate.service.d.ts +43 -42
  455. package/lib/services/certificate.service.d.ts.map +1 -0
  456. package/lib/services/discuss-utils.service.d.ts +34 -33
  457. package/lib/services/discuss-utils.service.d.ts.map +1 -0
  458. package/lib/services/editor.service.d.ts +18 -17
  459. package/lib/services/editor.service.d.ts.map +1 -0
  460. package/lib/services/load-check.service.d.ts +9 -8
  461. package/lib/services/load-check.service.d.ts.map +1 -0
  462. package/lib/services/loader.service.d.ts +17 -16
  463. package/lib/services/loader.service.d.ts.map +1 -0
  464. package/lib/services/mobile-apps.service.d.ts +39 -38
  465. package/lib/services/mobile-apps.service.d.ts.map +1 -0
  466. package/lib/services/netcore.service.d.ts +34 -33
  467. package/lib/services/netcore.service.d.ts.map +1 -0
  468. package/lib/services/nps-grid.service.d.ts +16 -15
  469. package/lib/services/nps-grid.service.d.ts.map +1 -0
  470. package/lib/services/otp.service.d.ts +21 -20
  471. package/lib/services/otp.service.d.ts.map +1 -0
  472. package/lib/services/profile-v2.service.d.ts +21 -20
  473. package/lib/services/profile-v2.service.d.ts.map +1 -0
  474. package/lib/services/reset-ratings.service.d.ts +9 -8
  475. package/lib/services/reset-ratings.service.d.ts.map +1 -0
  476. package/lib/services/resource-download-helper.service.d.ts +30 -29
  477. package/lib/services/resource-download-helper.service.d.ts.map +1 -0
  478. package/lib/services/timer.service.d.ts +10 -9
  479. package/lib/services/timer.service.d.ts.map +1 -0
  480. package/lib/services/title-tag.service.d.ts +22 -21
  481. package/lib/services/title-tag.service.d.ts.map +1 -0
  482. package/lib/services/user-profile.service.d.ts +25 -24
  483. package/lib/services/user-profile.service.d.ts.map +1 -0
  484. package/lib/services/viewer-data.service.d.ts +59 -58
  485. package/lib/services/viewer-data.service.d.ts.map +1 -0
  486. package/lib/services/viewer-util.service.d.ts +77 -76
  487. package/lib/services/viewer-util.service.d.ts.map +1 -0
  488. package/lib/share-toc/share-toc/share-toc.component.d.ts +57 -56
  489. package/lib/share-toc/share-toc/share-toc.component.d.ts.map +1 -0
  490. package/lib/share-toc/share-toc.module.d.ts +33 -32
  491. package/lib/share-toc/share-toc.module.d.ts.map +1 -0
  492. package/package.json +1 -1
  493. package/public-api.d.ts +59 -56
  494. package/public-api.d.ts.map +1 -0
  495. package/sunbird-cb-toc.d.ts.map +1 -0
@@ -1,1148 +1,1202 @@
1
- import { Component, Input } from '@angular/core';
2
- import { NsContent } from '../../../../_services/widget-content.model';
3
- import { viewerRouteGenerator } from '../../../../_services/viewer-route-util';
4
- import { WsEvents } from '@sunbird-cb/utils-v2';
5
- import { CertificateDialogComponent } from '../../certificate-dialog/certificate-dialog.component';
6
- import { animate, style, transition, trigger } from '@angular/animations';
7
- /* tslint:disable*/
8
- import _ from 'lodash';
9
- import moment from 'moment';
10
- import * as i0 from "@angular/core";
11
- import * as i1 from "@sunbird-cb/utils-v2";
12
- import * as i2 from "@angular/material/legacy-dialog";
13
- import * as i3 from "../../../../services/certificate.service";
14
- import * as i4 from "../../../../services/app-toc.service";
15
- import * as i5 from "@sunbird-cb/consumption";
16
- import * as i6 from "../../../../services/resource-download-helper.service";
17
- import * as i7 from "@angular/material/legacy-snack-bar";
18
- import * as i8 from "@angular/common";
19
- import * as i9 from "@angular/router";
20
- import * as i10 from "@angular/material/icon";
21
- import * as i11 from "@angular/material/menu";
22
- import * as i12 from "@angular/material/progress-spinner";
23
- import * as i13 from "../../content-progress/content-progress.component";
24
- import * as i14 from "ng-circle-progress";
25
- import * as i15 from "@angular/material/legacy-tooltip";
26
- import * as i16 from "@ngx-translate/core";
27
- import * as i17 from "../pipes/truncate.pipe";
28
- export class AppTocContentCardV2Component {
29
- constructor(events, dialog, renderer, certificateService, appTocSvc, contentLangSvc, resourceDownloadHelperSvc, configSvc, snackBar) {
30
- this.events = events;
31
- this.dialog = dialog;
32
- this.renderer = renderer;
33
- this.certificateService = certificateService;
34
- this.appTocSvc = appTocSvc;
35
- this.contentLangSvc = contentLangSvc;
36
- this.resourceDownloadHelperSvc = resourceDownloadHelperSvc;
37
- this.configSvc = configSvc;
38
- this.snackBar = snackBar;
39
- this.content = null;
40
- this.expandAll = false;
41
- this.forPreview = false;
42
- this.componentName = 'toc';
43
- this.expandActive = true;
44
- this.hierarchyMapData = {};
45
- this.batchData = null;
46
- this.isPreAssessment = false;
47
- this.baseContentReadData = null;
48
- this.mlCourse = null;
49
- this.parentMilestoneLocked = false; // Passed from parent when inside a locked milestone
50
- this.hasContentStructure = false;
51
- this.downloadCertificateLoading = false;
52
- this.enumContentTypes = NsContent.EDisplayContentTypes;
53
- this.contentStructure = {
54
- assessment: 0,
55
- finalTest: 0,
56
- course: 0,
57
- handsOn: 0,
58
- interactiveVideo: 0,
59
- learningModule: 0,
60
- other: 0,
61
- pdf: 0,
62
- survey: 0,
63
- podcast: 0,
64
- practiceTest: 0,
65
- quiz: 0,
66
- video: 0,
67
- webModule: 0,
68
- webPage: 0,
69
- youtube: 0,
70
- interactivecontent: 0,
71
- offlineSession: 0,
72
- };
73
- this.defaultThumbnail = '';
74
- this.viewChildren = false;
75
- this.primaryCategory = NsContent.EPrimaryCategory;
76
- this.pageScrollSubscription = null;
77
- this.achievementLoading = false;
78
- // Cached computed properties for performance optimization
79
- this._cachedIsCollection = false;
80
- this._cachedIsModule = false;
81
- this._cachedIsResource = false;
82
- this._cachedIsMilestone = false;
83
- this._cachedIsMilestoneLocked = false;
84
- this._cachedIsParentMilestoneLocked = false;
85
- this._cachedIsContentUnlocked = true;
86
- this._cachedCheckForCuratedProgram = false;
87
- this._cachedIsMilestoneAssessment = false;
88
- this._cachedIsMilestoneAssessmentLocked = false;
89
- this._cachedResourceLink = { url: '', queryParams: {} };
90
- this._cacheInitialized = false;
91
- }
92
- ngOnInit() {
93
- this.evaluateImmediateChildrenStructure();
94
- this.initializeComputedProperties();
95
- // this.route.data.subscribe(data => {
96
- // this.defaultThumbnail = data.configData.data.logos.defaultContent
97
- // }
98
- // )
99
- this.resourceScroll();
100
- }
101
- /**
102
- * Initialize all computed properties once to avoid expensive getter calculations
103
- * on every change detection cycle
104
- */
105
- initializeComputedProperties() {
106
- this.computeAllCachedProperties();
107
- }
108
- /**
109
- * Compute all cached properties at once for performance optimization
110
- */
111
- computeAllCachedProperties() {
112
- if (!this.content) {
113
- this._cacheInitialized = false;
114
- return;
115
- }
116
- const contentId = this.content.identifier;
117
- const hashData = this.hierarchyMapData && this.hierarchyMapData[contentId];
118
- // Use hashmap data if available for pre-computed values
119
- if (hashData) {
120
- this._cachedIsCollection = hashData.isCollection !== undefined ?
121
- hashData.isCollection : this.content.mimeType === NsContent.EMimeTypes.COLLECTION;
122
- this._cachedIsModule = hashData.isModule !== undefined ?
123
- hashData.isModule : this.content.primaryCategory === NsContent.EPrimaryCategory.MODULE;
124
- this._cachedIsResource = hashData.isResource !== undefined ?
125
- hashData.isResource : this.computeIsResource();
126
- this._cachedIsMilestone = hashData.isMilestone !== undefined ?
127
- hashData.isMilestone : this.computeIsMilestone();
128
- this._cachedIsMilestoneLocked = hashData.computedIsLocked !== undefined ?
129
- hashData.computedIsLocked : this.computeIsMilestoneLocked();
130
- this._cachedIsParentMilestoneLocked = hashData.isParentMilestoneLocked !== undefined ?
131
- hashData.isParentMilestoneLocked : this.computeIsParentMilestoneLocked();
132
- }
133
- else {
134
- // Fallback to direct computation if hashmap not available
135
- this._cachedIsCollection = this.content.mimeType === NsContent.EMimeTypes.COLLECTION;
136
- this._cachedIsModule = this.content.primaryCategory === NsContent.EPrimaryCategory.MODULE;
137
- this._cachedIsResource = this.computeIsResource();
138
- this._cachedIsMilestone = this.computeIsMilestone();
139
- this._cachedIsMilestoneLocked = this.computeIsMilestoneLocked();
140
- this._cachedIsParentMilestoneLocked = this.computeIsParentMilestoneLocked();
141
- }
142
- this._cachedCheckForCuratedProgram = this.computeCheckForCuratedProgram();
143
- this._cachedIsContentUnlocked = this.computeIsContentUnlocked();
144
- this._cachedIsMilestoneAssessment = this.computeIsMilestoneAssessment();
145
- this._cachedIsMilestoneAssessmentLocked = this.computeIsMilestoneAssessmentLocked();
146
- this._cachedResourceLink = this.computeResourceLink();
147
- this._cacheInitialized = true;
148
- }
149
- computeIsResource() {
150
- if (!this.content)
151
- return false;
152
- return (this.content.primaryCategory === NsContent.EPrimaryCategory.RESOURCE ||
153
- this.content.primaryCategory === NsContent.EPrimaryCategory.PRACTICE_RESOURCE ||
154
- this.content.primaryCategory === NsContent.EPrimaryCategory.FINAL_ASSESSMENT ||
155
- this.content.primaryCategory === NsContent.EPrimaryCategory.COMP_ASSESSMENT);
156
- }
157
- computeIsMilestone() {
158
- if (!this.content)
159
- return false;
160
- const primaryCat = this.content.primaryCategory;
161
- const courseCat = this.content.courseCategory;
162
- return primaryCat === 'Milestone' || courseCat === 'Milestone';
163
- }
164
- computeCheckForCuratedProgram() {
165
- if (this.content && this.content.parent && this.hierarchyMapData && this.hierarchyMapData[this.content.parent]) {
166
- const parentData = this.hierarchyMapData[this.content.parent];
167
- return parentData && parentData.primaryCategory === NsContent.EPrimaryCategory.CURATED_PROGRAM &&
168
- parentData.compatibilityLevel >= 5 &&
169
- parentData.contextLockingType === NsContent.EContextLockingType.COURSE_ASSESSMENT_ONLY;
170
- }
171
- return false;
172
- }
173
- computeIsContentUnlocked() {
174
- if (this._cachedCheckForCuratedProgram) {
175
- if (this.content && this.content.parent && this.hierarchyMapData && this.hierarchyMapData[this.content.parent]) {
176
- const parentData = this.hierarchyMapData[this.content.parent];
177
- let completedLeafNodes = [];
178
- parentData.leafNodes.forEach((_ele) => {
179
- if (this.hierarchyMapData && this.hierarchyMapData[_ele]) {
180
- const childData = this.hierarchyMapData[_ele];
181
- if (childData && childData.completionStatus === 2) {
182
- completedLeafNodes.push(childData);
183
- }
184
- }
185
- });
186
- return completedLeafNodes.length >= parentData.leafNodesCount - 1;
187
- }
188
- return false;
189
- }
190
- return true;
191
- }
192
- computeResourceLink() {
193
- if (this.content) {
194
- let mimeType = '';
195
- if (this.content && this.content.courseCategory === 'Pre Enrolment Assessment' &&
196
- this.content.mimeType === 'application/vnd.ekstep.content-collection') {
197
- mimeType = 'application/vnd.sunbird.questionset';
198
- this.content.mimeType = NsContent.EMimeTypes.FINAL_ASSESSMENT;
199
- }
200
- else {
201
- mimeType = this.content.mimeType;
202
- }
203
- const selectedLanguage = this.mlCourse ? this.contentLangSvc.getSelectedLanguage(this.mlCourse) : undefined;
204
- return viewerRouteGenerator(this.content.identifier, mimeType, this.baseContentReadData?.identifier || this.rootId, this.baseContentReadData?.contentType || this.rootContentType, this.forPreview, this.content.primaryCategory, this.batchId, this.content?.name || this.baseContentReadData?.name, (selectedLanguage ? selectedLanguage.langId : null), (selectedLanguage ? selectedLanguage.identifier : null));
205
- }
206
- return { url: '', queryParams: {} };
207
- }
208
- computeIsMilestoneLocked() {
209
- // Only apply milestone locking for Learning Pathway content
210
- if (!this.baseContentReadData || this.baseContentReadData.courseCategory !== 'Learning Pathway') {
211
- return false;
212
- }
213
- if (!this.content) {
214
- return false;
215
- }
216
- // Check if current content is a Milestone
217
- if (!this._cachedIsMilestone && !this.computeIsMilestone()) {
218
- return false;
219
- }
220
- // Check if hashmap has pre-computed locking status (preferred - computed by service)
221
- const hashData = this.hierarchyMapData && this.hierarchyMapData[this.content.identifier];
222
- console.log(`computeIsMilestoneLocked for ${this.content.identifier} (${this.content.name}):`, {
223
- hashData,
224
- computedIsLocked: hashData?.computedIsLocked,
225
- contentIsLocked: this.content.isLocked
226
- });
227
- if (hashData && hashData.computedIsLocked !== undefined) {
228
- return hashData.computedIsLocked;
229
- }
230
- // If milestone has isLocked flag explicitly set to false, it's unlocked
231
- if (this.content.isLocked === false) {
232
- return false;
233
- }
234
- // Fallback: All milestones are locked by default until computed otherwise
235
- // This ensures proper locking until the hashmap is updated with progress
236
- return true;
237
- }
238
- computeIsParentMilestoneLocked() {
239
- if (this.parentMilestoneLocked) {
240
- return true;
241
- }
242
- if (!this.baseContentReadData || this.baseContentReadData.courseCategory !== 'Learning Pathway') {
243
- return false;
244
- }
245
- if (!this.content || !this.hierarchyMapData) {
246
- return false;
247
- }
248
- // Check hashmap for pre-computed value
249
- const hashData = this.hierarchyMapData[this.content.identifier];
250
- if (hashData && hashData.isParentMilestoneLocked !== undefined) {
251
- return hashData.isParentMilestoneLocked;
252
- }
253
- // Traverse up the hierarchy to find if any ancestor is a locked Milestone
254
- let currentParentId = this.content.parent;
255
- const maxDepth = 5;
256
- let depth = 0;
257
- while (currentParentId && depth < maxDepth) {
258
- const parentData = this.hierarchyMapData[currentParentId];
259
- if (parentData) {
260
- if ((parentData.isMilestone || parentData.primaryCategory === 'Milestone' || parentData.courseCategory === 'Milestone') &&
261
- (parentData.computedIsLocked || parentData.isLocked)) {
262
- return true;
263
- }
264
- currentParentId = parentData.parent;
265
- }
266
- else {
267
- break;
268
- }
269
- depth++;
270
- }
271
- return false;
272
- }
273
- /**
274
- * Check if current content is a milestone assessment (Course Assessment or Final Assessment inside a Milestone)
275
- */
276
- computeIsMilestoneAssessment() {
277
- if (!this.baseContentReadData || this.baseContentReadData.courseCategory !== 'Learning Pathway') {
278
- return false;
279
- }
280
- if (!this.content || !this.hierarchyMapData) {
281
- return false;
282
- }
283
- // Check if this is an assessment
284
- const isAssessment = this.content.primaryCategory === 'Course Assessment' ||
285
- this.content.courseCategory === 'Course Assessment' ||
286
- (this.content.name && this.content.name.toLowerCase().includes('assessment'));
287
- if (!isAssessment) {
288
- return false;
289
- }
290
- // Check if the parent or grandparent is a milestone (since assessments can be inside courses inside milestones)
291
- if (this.content.parent && this.hierarchyMapData[this.content.parent]) {
292
- const parentData = this.hierarchyMapData[this.content.parent];
293
- // Check if direct parent is a milestone
294
- if (parentData.isMilestone || parentData.primaryCategory === 'Milestone' || parentData.courseCategory === 'Milestone') {
295
- return true;
296
- }
297
- // Check if grandparent is a milestone (for assessments inside courses inside milestones)
298
- if (parentData.parent && this.hierarchyMapData[parentData.parent]) {
299
- const grandparentData = this.hierarchyMapData[parentData.parent];
300
- return grandparentData.isMilestone || grandparentData.primaryCategory === 'Milestone' || grandparentData.courseCategory === 'Milestone';
301
- }
302
- }
303
- return false;
304
- }
305
- /**
306
- * Check if milestone assessment should be locked
307
- * Assessment is locked if:
308
- * 1. It's an assessment within a milestone
309
- * 2. The parent milestone is unlocked (otherwise handled by parent milestone lock)
310
- * 3. NOT all mandatory content in the same milestone is completed
311
- */
312
- computeIsMilestoneAssessmentLocked() {
313
- // Only apply to assessments within milestones
314
- if (!this._cachedIsMilestoneAssessment && !this.computeIsMilestoneAssessment()) {
315
- return false;
316
- }
317
- // Check if hashmap has pre-computed assessment locking status
318
- const hashData = this.hierarchyMapData && this.hierarchyMapData[this.content?.identifier || ''];
319
- if (hashData && hashData.isAssessmentLocked !== undefined) {
320
- return hashData.isAssessmentLocked;
321
- }
322
- // If already completed, don't lock
323
- if (this.content && (this.content.completionStatus === 2 ||
324
- (this.content.completionPercentage && this.content.completionPercentage >= 100))) {
325
- return false;
326
- }
327
- // Find the milestone ID (could be parent or grandparent)
328
- let milestoneId;
329
- let milestone;
330
- // Check if direct parent is milestone
331
- if (this.content?.parent && this.hierarchyMapData && this.hierarchyMapData[this.content.parent]) {
332
- const parentData = this.hierarchyMapData[this.content.parent];
333
- if (parentData.isMilestone || parentData.primaryCategory === 'Milestone' || parentData.courseCategory === 'Milestone') {
334
- milestoneId = this.content.parent;
335
- milestone = parentData;
336
- }
337
- else if (parentData.parent && this.hierarchyMapData[parentData.parent]) {
338
- // Check if grandparent is milestone
339
- const grandparentData = this.hierarchyMapData[parentData.parent];
340
- if (grandparentData.isMilestone || grandparentData.primaryCategory === 'Milestone' || grandparentData.courseCategory === 'Milestone') {
341
- milestoneId = parentData.parent;
342
- milestone = grandparentData;
343
- }
344
- }
345
- }
346
- if (!milestoneId || !milestone) {
347
- return false;
348
- }
349
- // If the parent milestone itself is locked, don't add additional locking
350
- // (the parent lock will handle it)
351
- if (milestone.computedIsLocked || milestone.isLocked) {
352
- return false;
353
- }
354
- // Check if all mandatory content in the milestone is completed
355
- let mandatoryCount = 0;
356
- let completedMandatoryCount = 0;
357
- // Check all items in hashmap that belong to this milestone
358
- for (const key of Object.keys(this.hierarchyMapData)) {
359
- const item = this.hierarchyMapData[key];
360
- // Check if this item belongs to the milestone (direct child or nested)
361
- // Most content will be under courses that are under milestone
362
- let itemBelongsToMilestone = false;
363
- if (item.parent === milestoneId) {
364
- itemBelongsToMilestone = true;
365
- }
366
- else if (item.parent && this.hierarchyMapData[item.parent]) {
367
- // Check if parent is a course under this milestone
368
- const parentItem = this.hierarchyMapData[item.parent];
369
- if (parentItem.parent === milestoneId && parentItem.primaryCategory === 'Course') {
370
- itemBelongsToMilestone = true;
371
- }
372
- }
373
- if (!itemBelongsToMilestone)
374
- continue;
375
- // Skip assessments - we're checking if learning content is complete
376
- const isItemAssessment = item.primaryCategory === 'Course Assessment' ||
377
- item.primaryCategory === 'Final Assessment' ||
378
- item.primaryCategory === 'Standalone Assessment' ||
379
- item.courseCategory === 'Course Assessment' ||
380
- item.mimeType === 'application/vnd.sunbird.questionset' ||
381
- item.mimeType === 'application/quiz' ||
382
- (item.name && item.name.toLowerCase().includes('assessment'));
383
- if (isItemAssessment)
384
- continue;
385
- // Check if this content is mandatory (courses and non-optional content)
386
- // By default, courses are mandatory unless explicitly marked otherwise
387
- if (item.isMandatory !== false && (item.primaryCategory === 'Course' || item.isMandatory === true)) {
388
- // Count all courses and mandatory items as they need to be completed
389
- mandatoryCount++;
390
- const isCompleted = item.completionStatus === 2 || item.status === 2 ||
391
- item.completionPercentage >= 100 || item.progress >= 100;
392
- if (isCompleted) {
393
- completedMandatoryCount++;
394
- }
395
- }
396
- }
397
- // If there are no mandatory items, assessment is unlocked
398
- if (mandatoryCount === 0) {
399
- return false;
400
- }
401
- // Lock assessment if not all mandatory items are completed
402
- const allMandatoryComplete = completedMandatoryCount >= mandatoryCount;
403
- return !allMandatoryComplete;
404
- }
405
- // FOR RIGHT SIDE RESOURCE SCROLL ON TOC PAGE
406
- resourceScroll() {
407
- this.pageScrollSubscription = this.appTocSvc.updatePageScroll.subscribe((value) => {
408
- if (value) {
409
- setTimeout(() => {
410
- this.scrollView();
411
- }, 700);
412
- }
413
- });
414
- }
415
- // TO UPDATE RESOURCE BEHAVOUR SUBJECT FOR RESOURCE SCROLL
416
- changeResource() {
417
- this.appTocSvc.getPageScroll.next(true);
418
- }
419
- ngOnChanges(changes) {
420
- let shouldRecomputeCache = false;
421
- for (const property in changes) {
422
- if (property === 'expandAll') {
423
- this.viewChildren = this.expandAll;
424
- }
425
- if (property === 'pathSet' && changes['pathSet']) {
426
- let currentValue = changes['pathSet'].currentValue;
427
- let previousValue = changes['pathSet'].previousValue;
428
- if (currentValue && previousValue) {
429
- const eqSet = (xs, ys) => xs.size === ys.size &&
430
- [...xs].every((x) => ys.has(x));
431
- if (!eqSet(previousValue, currentValue)) { }
432
- }
433
- // if(previousValue === undefined){
434
- // setTimeout(()=>{
435
- // },700)
436
- // }
437
- }
438
- // this.appTocSvc.getPageScroll.next(true)
439
- if (property === 'hierarchyMapData') {
440
- if (_.isEmpty(changes['hierarchyMapData'].currentValue)) {
441
- // this.loadingOverallPRogress = true
442
- }
443
- else {
444
- if (this.content) {
445
- this.updateChildParentMap(this.content.identifier);
446
- }
447
- shouldRecomputeCache = true;
448
- }
449
- }
450
- // Recompute cache when critical inputs change
451
- if (property === 'content' || property === 'baseContentReadData' ||
452
- property === 'batchId' || property === 'forPreview' ||
453
- property === 'parentMilestoneLocked' || property === 'mlCourse') {
454
- shouldRecomputeCache = true;
455
- }
456
- }
457
- // Recompute all cached properties if needed
458
- if (shouldRecomputeCache) {
459
- this.computeAllCachedProperties();
460
- }
461
- // console.log('pre assessment content---', this.content)
462
- // console.log('this.hierarchyMapData---', this.hierarchyMapData)
463
- }
464
- check(content) {
465
- if (this.expandActive) {
466
- content.viewChildren = this.pathSet && this.pathSet.has(content.identifier) || content.viewChildren;
467
- }
468
- return content.viewChildren;
469
- }
470
- get isCollection() {
471
- if (this._cacheInitialized) {
472
- return this._cachedIsCollection;
473
- }
474
- if (this.content) {
475
- return this.content.mimeType === NsContent.EMimeTypes.COLLECTION;
476
- }
477
- return false;
478
- }
479
- get isModule() {
480
- if (this._cacheInitialized) {
481
- return this._cachedIsModule;
482
- }
483
- if (this.content) {
484
- return this.content.primaryCategory === NsContent.EPrimaryCategory.MODULE;
485
- }
486
- return false;
487
- }
488
- checkModule(content) {
489
- if (content) {
490
- return content.primaryCategory === NsContent.EPrimaryCategory.MODULE;
491
- }
492
- return false;
493
- }
494
- checkIsModule(content) {
495
- if (content) {
496
- return content.primaryCategory === NsContent.EPrimaryCategory.MODULE;
497
- }
498
- return false;
499
- }
500
- get isBatchInProgess() {
501
- if (this.batchData && (this.batchData.content && this.batchData.content.length) && this.batchData.enrolled) {
502
- const batchData = this.batchData.content[0];
503
- if (batchData && batchData.endDate) {
504
- const now = moment().format('YYYY-MM-DD');
505
- const startDate = moment(batchData.startDate).format('YYYY-MM-DD');
506
- const endDate = batchData.endDate ? moment(batchData.endDate).format('YYYY-MM-DD') : now;
507
- return (
508
- // batch.status &&
509
- moment(startDate).isSameOrBefore(now)
510
- && moment(endDate).isSameOrAfter(now));
511
- }
512
- return true;
513
- }
514
- return false;
515
- }
516
- get isResource() {
517
- if (this._cacheInitialized) {
518
- return this._cachedIsResource;
519
- }
520
- return this.computeIsResource();
521
- }
522
- get resourceLink() {
523
- if (this._cacheInitialized) {
524
- return this._cachedResourceLink;
525
- }
526
- return this.computeResourceLink();
527
- }
528
- progressColor() {
529
- // if (this.currentProgress <= 30) {
530
- // return '#D13924'
531
- // } if (this.currentProgress > 30 && this.currentProgress <= 70) {
532
- // return '#E99E38'
533
- // }
534
- // if (this.currentProgress > 70 && this.currentProgress <= 100) {
535
- // return '#1D8923'
536
- // }
537
- return '#1D8923';
538
- }
539
- progressColor2() {
540
- return '#f27d00';
541
- }
542
- evaluateImmediateChildrenStructure() {
543
- if (this.content && this.content.children && this.content.children.length) {
544
- this.content.children.forEach((child) => {
545
- if (child.primaryCategory === NsContent.EPrimaryCategory.COURSE) {
546
- this.contentStructure.course += 1;
547
- }
548
- else if (child.primaryCategory === NsContent.EPrimaryCategory.KNOWLEDGE_ARTIFACT) {
549
- this.contentStructure.other += 1;
550
- }
551
- else if (child.primaryCategory === NsContent.EPrimaryCategory.MODULE) {
552
- this.contentStructure.learningModule += 1;
553
- }
554
- else if (child.primaryCategory === NsContent.EPrimaryCategory.OFFLINE_SESSION) {
555
- this.contentStructure.offlineSession += 1;
556
- }
557
- else if (child.primaryCategory === NsContent.EPrimaryCategory.RESOURCE) {
558
- switch (child.mimeType) {
559
- case NsContent.EMimeTypes.HANDS_ON:
560
- this.contentStructure.handsOn += 1;
561
- break;
562
- case NsContent.EMimeTypes.MP3:
563
- this.contentStructure.podcast += 1;
564
- break;
565
- case NsContent.EMimeTypes.MP4:
566
- case NsContent.EMimeTypes.M3U8:
567
- this.contentStructure.video += 1;
568
- break;
569
- case NsContent.EMimeTypes.INTERACTION:
570
- this.contentStructure.interactiveVideo += 1;
571
- break;
572
- case NsContent.EMimeTypes.PDF:
573
- this.contentStructure.pdf += 1;
574
- break;
575
- case NsContent.EMimeTypes.OFFLINE_SESSION:
576
- this.contentStructure.offlineSession += 1;
577
- break;
578
- case NsContent.EMimeTypes.SURVEY:
579
- this.contentStructure.survey += 1;
580
- break;
581
- case NsContent.EMimeTypes.HTML:
582
- this.contentStructure.webPage += 1;
583
- break;
584
- case NsContent.EMimeTypes.QUIZ:
585
- if (child.resourceType === 'Assessment') {
586
- this.contentStructure.assessment += 1;
587
- }
588
- else {
589
- this.contentStructure.quiz += 1;
590
- }
591
- break;
592
- case NsContent.EMimeTypes.PRACTICE_RESOURCE:
593
- // case NsContent.EMimeTypes.FINAL_ASSESSMENT:
594
- // case NsContent.EMimeTypes.PRACTICE_RESOURCE:
595
- this.contentStructure.practiceTest += 1;
596
- break;
597
- case NsContent.EMimeTypes.WEB_MODULE:
598
- this.contentStructure.webModule += 1;
599
- break;
600
- case NsContent.EMimeTypes.YOUTUBE:
601
- this.contentStructure.youtube += 1;
602
- break;
603
- default:
604
- this.contentStructure.other += 1;
605
- break;
606
- }
607
- }
608
- });
609
- }
610
- for (const key in this.contentStructure) {
611
- if (this.contentStructure[key] > 0) {
612
- this.hasContentStructure = true;
613
- }
614
- }
615
- }
616
- get contextPath() {
617
- return {
618
- contextId: this.rootId,
619
- contextPath: this.rootContentType,
620
- batchId: this.batchId,
621
- };
622
- }
623
- contentTrackBy(_index, content) {
624
- if (!content) {
625
- return null;
626
- }
627
- return content.identifier;
628
- }
629
- raiseTelemetry() {
630
- // if (this.forPreview) { return }
631
- if (this.content) {
632
- this.events.raiseInteractTelemetry({
633
- type: 'click',
634
- subType: `card-tocContentCard`,
635
- // id: this.content.identifier || '',
636
- }, {
637
- // contentId: this.content.identifier || '',
638
- // contentType: this.content.primaryCategory,
639
- id: this.content.identifier || '',
640
- type: this.content.primaryCategory,
641
- rollup: {
642
- l1: this.rootId || '',
643
- },
644
- ver: `${this.content.version}${''}`,
645
- }, {
646
- pageIdExt: `${_.camelCase(this.content.primaryCategory)}-card`,
647
- module: _.camelCase(this.content.primaryCategory),
648
- });
649
- }
650
- }
651
- get isAllowed() {
652
- if (this.content) {
653
- return !(NsContent.UN_SUPPORTED_DATA_TYPES_FOR_NON_BATCH_USERS.indexOf(this.content.mimeType) >= 0);
654
- }
655
- return false;
656
- }
657
- get isEnabled() {
658
- return true;
659
- }
660
- get isEnrolled() {
661
- return this.batchId ? true : false;
662
- }
663
- updateChildParentMap(identifier) {
664
- if (this.hierarchyMapData && this.hierarchyMapData[identifier]) {
665
- let localContentData = this.hierarchyMapData[identifier];
666
- if (!(localContentData.primaryCategory === NsContent.EPrimaryCategory.RESOURCE
667
- || localContentData.primaryCategory === NsContent.EPrimaryCategory.PRACTICE_RESOURCE
668
- || localContentData.primaryCategory === NsContent.EPrimaryCategory.FINAL_ASSESSMENT
669
- || localContentData.primaryCategory === NsContent.EPrimaryCategory.COMP_ASSESSMENT)) {
670
- // real percent logic
671
- // const total = localContentData.leafNodes.reduce((sum: number, childId: string) => {
672
- // return sum + Number(this.hierarchyMapData[childId].completionPercentage || 0)
673
- // }, 0)
674
- // console.log('total ', total)
675
- // if(total > 0) {
676
- // this.hierarchyMapData[identifier]['completionPercentage'] = total / _.toInteger(_.get(this.hierarchyMapData[identifier], 'leafNodesCount'))
677
- // }
678
- if (localContentData.primaryCategory === NsContent.EPrimaryCategory.MODULE) {
679
- this.hierarchyMapData[identifier]['duration'] = this.hierarchyMapData[identifier].leafNodes.reduce((sum, childID) => {
680
- if (this.hierarchyMapData && this.hierarchyMapData[childID]) {
681
- return sum + Number(this.hierarchyMapData[childID].duration || this.hierarchyMapData[childID].expectedDuration || 0);
682
- }
683
- }, 0);
684
- }
685
- // tslint:disable
686
- const completedItems = _.filter(this.hierarchyMapData[identifier].leafNodes, r => (this.hierarchyMapData[r] && (this.hierarchyMapData[r].completionStatus === 2 || this.hierarchyMapData[r].completionPercentage === 100)));
687
- const totalCount = _.toInteger(_.get(this.hierarchyMapData[identifier], 'leafNodesCount')) || 1;
688
- this.hierarchyMapData[identifier]['completionPercentage'] = Number(((completedItems.length / totalCount) * 100).toFixed());
689
- this.hierarchyMapData[identifier]['completionStatus'] = (this.hierarchyMapData[identifier].completionPercentage >= 100) ? 2 : 1;
690
- }
691
- return this.hierarchyMapData[identifier];
692
- }
693
- return '';
694
- }
695
- getCompletionPercentage(identifier) {
696
- // console.log('getCompletionPercentage', identifier)
697
- // console.log('this.hierarchyMapData[identifier] : ', this.hierarchyMapData[identifier])
698
- // const item = this.updateChildParentMap(identifier)
699
- let percent = this.hierarchyMapData && this.hierarchyMapData[identifier] && this.hierarchyMapData[identifier].completionPercentage || 0;
700
- return this.roundIfDecimal(percent);
701
- }
702
- roundIfDecimal(value) {
703
- if (!Number.isInteger(value)) {
704
- return parseFloat(value.toFixed(2));
705
- }
706
- return value;
707
- }
708
- getCompletionStatus(identifier) {
709
- // console.log('getCompletionStatus')
710
- // const item = this.updateChildParentMap(identifier)
711
- return this.hierarchyMapData && this.hierarchyMapData[identifier] && this.hierarchyMapData[identifier].completionStatus;
712
- }
713
- openCertificateDialog(certData) {
714
- const cet = certData;
715
- this.dialog.open(CertificateDialogComponent, {
716
- // height: '400px',
717
- width: '1300px',
718
- data: { cet },
719
- // panelClass: 'custom-dialog-container',
720
- });
721
- }
722
- scrollView() {
723
- try {
724
- let errorField = this.renderer.selectRootElement('.resource-container .resource-active');
725
- if (errorField) {
726
- errorField.scrollIntoView({ behavior: "smooth", block: "start", inline: "nearest" });
727
- }
728
- if (this.componentName === 'toc') {
729
- if (errorField) {
730
- const rect = errorField.getBoundingClientRect();
731
- if (rect.top - 420 > 0) {
732
- window.scroll(420, rect.top - 148);
733
- }
734
- }
735
- }
736
- setTimeout(() => {
737
- this.appTocSvc.getPageScroll.next(false);
738
- }, 700);
739
- // else {
740
- // errorField.scrollIntoView({ behavior: "smooth", block: "start", inline: "nearest" });
741
- // const rect = errorField.getBoundingClientRect();
742
- // errorField.scroll(0,rect.top-56)
743
- // }
744
- }
745
- catch (err) {
746
- }
747
- }
748
- downloadCertificate(certificateData) {
749
- this.events.raiseInteractTelemetry({
750
- type: WsEvents.EnumInteractTypes.CLICK,
751
- id: 'view-certificate',
752
- subType: WsEvents.EnumInteractSubTypes.CERTIFICATE,
753
- }, {
754
- id: certificateData,
755
- type: WsEvents.EnumInteractSubTypes.CERTIFICATE,
756
- });
757
- if (certificateData) {
758
- this.downloadCertificateLoading = true;
759
- let certData = certificateData;
760
- this.certificateService.downloadCertificate_v2(certData).subscribe((res) => {
761
- this.downloadCertificateLoading = false;
762
- const cet = res.result.printUri;
763
- this.dialog.open(CertificateDialogComponent, {
764
- width: '1300px',
765
- data: { cet, certId: certData.identifier },
766
- });
767
- });
768
- }
769
- else {
770
- this.downloadCertificateLoading = false;
771
- }
772
- }
773
- ngOnDestroy() {
774
- if (this.pageScrollSubscription) {
775
- this.pageScrollSubscription.unsubscribe();
776
- }
777
- }
778
- get checkForCuratedProgram() {
779
- if (this._cacheInitialized) {
780
- return this._cachedCheckForCuratedProgram;
781
- }
782
- return this.computeCheckForCuratedProgram();
783
- }
784
- get isContentUnlocked() {
785
- if (this._cacheInitialized) {
786
- return this._cachedIsContentUnlocked;
787
- }
788
- return this.computeIsContentUnlocked();
789
- }
790
- get isParentMilestoneLocked() {
791
- if (this._cacheInitialized) {
792
- return this._cachedIsParentMilestoneLocked;
793
- }
794
- return this.computeIsParentMilestoneLocked();
795
- }
796
- get isMilestoneLocked() {
797
- if (this._cacheInitialized) {
798
- return this._cachedIsMilestoneLocked;
799
- }
800
- return this.computeIsMilestoneLocked();
801
- }
802
- get isMilestoneAssessment() {
803
- if (this._cacheInitialized) {
804
- return this._cachedIsMilestoneAssessment;
805
- }
806
- return this.computeIsMilestoneAssessment();
807
- }
808
- get isMilestoneAssessmentLocked() {
809
- if (this._cacheInitialized) {
810
- return this._cachedIsMilestoneAssessmentLocked;
811
- }
812
- return this.computeIsMilestoneAssessmentLocked();
813
- }
814
- /**
815
- * Check if a milestone's mandatory courses and assessment are completed.
816
- * Looks at the content hierarchy to find children of the milestone.
817
- */
818
- checkMilestoneContentCompletion(milestoneId) {
819
- if (!this.baseContentReadData || !this.baseContentReadData.children || !this.hierarchyMapData) {
820
- // Fallback: Try to find assessment completion in hashmap for this milestone
821
- return this.checkMilestoneAssessmentCompletion(milestoneId);
822
- }
823
- // Find the milestone in the content hierarchy
824
- const milestoneContent = this.findContentInHierarchy(this.baseContentReadData, milestoneId);
825
- if (!milestoneContent || !milestoneContent.children) {
826
- return this.checkMilestoneAssessmentCompletion(milestoneId);
827
- }
828
- // Check all mandatory courses and assessments
829
- let allMandatoryComplete = true;
830
- let hasAssessment = false;
831
- let assessmentComplete = false;
832
- milestoneContent.children.forEach((child) => {
833
- const childData = this.hierarchyMapData[child.identifier];
834
- const isAssessment = child.primaryCategory === 'Course Assessment' ||
835
- child.courseCategory === 'Course Assessment' ||
836
- child.primaryCategory === 'Final Assessment';
837
- const isMandatory = child.mandatory === true || child.optionalReading !== true;
838
- if (isAssessment) {
839
- hasAssessment = true;
840
- if (childData && (childData.completionStatus === 2 || childData.completionPercentage >= 100)) {
841
- assessmentComplete = true;
842
- }
843
- }
844
- else if (isMandatory) {
845
- // Check if mandatory content is completed
846
- if (!childData || (childData.completionStatus !== 2 && childData.completionPercentage < 100)) {
847
- allMandatoryComplete = false;
848
- }
849
- }
850
- });
851
- console.log('Milestone content check:', { allMandatoryComplete, hasAssessment, assessmentComplete });
852
- // Milestone is complete if assessment is complete (mandatory courses optional based on requirements)
853
- return hasAssessment ? assessmentComplete : allMandatoryComplete;
854
- }
855
- /**
856
- * Fallback: Check if enough assessments are completed to unlock this milestone.
857
- * For milestone at index N, we need at least N completed assessments.
858
- * E.g., For M2 (index 1), we need 1 completed assessment (M1's assessment)
859
- * For M3 (index 2), we need 2 completed assessments (M1's and M2's)
860
- */
861
- checkMilestoneAssessmentCompletion(milestoneId) {
862
- if (!this.hierarchyMapData) {
863
- return false;
864
- }
865
- // Extract milestone number from ID (M1 -> 1, M2 -> 2, etc.)
866
- const milestoneNum = parseInt(milestoneId.replace(/\D/g, '')) || 0;
867
- const requiredCompletedAssessments = milestoneNum - 1; // For M2, need 1; for M3, need 2
868
- console.log(`Milestone ${milestoneId} (num: ${milestoneNum}) requires ${requiredCompletedAssessments} completed assessments`);
869
- if (requiredCompletedAssessments <= 0) {
870
- return true; // First milestone, no requirements
871
- }
872
- // Count completed Course Assessments that are INSIDE milestones (have a parent)
873
- // Exclude pre-enrollment assessments at the root level (no parent or parent is Learning Pathway)
874
- let completedMilestoneAssessmentCount = 0;
875
- const learningPathwayId = this.baseContentReadData?.identifier;
876
- for (const key of Object.keys(this.hierarchyMapData)) {
877
- const item = this.hierarchyMapData[key];
878
- // Check if it's a completed Course Assessment
879
- if ((item.primaryCategory === 'Course Assessment' || item.courseCategory === 'Course Assessment') &&
880
- (item.completionStatus === 2 || item.completionPercentage >= 100)) {
881
- // Check if this assessment has a parent (meaning it's inside a course/milestone, not at root level)
882
- // Also exclude if parent is the Learning Pathway itself (pre-enrollment assessment)
883
- const hasParent = item.parent && item.parent !== learningPathwayId;
884
- if (hasParent) {
885
- completedMilestoneAssessmentCount++;
886
- console.log(`Found completed MILESTONE assessment: ${key}`, item);
887
- }
888
- else {
889
- console.log(`Skipping root-level/pre-enrollment assessment: ${key}`);
890
- }
891
- }
892
- }
893
- console.log(`Total completed MILESTONE assessments: ${completedMilestoneAssessmentCount}, Required: ${requiredCompletedAssessments}`);
894
- // If we have enough completed milestone assessments, unlock this milestone
895
- return completedMilestoneAssessmentCount >= requiredCompletedAssessments;
896
- }
897
- findContentInHierarchy(content, identifier) {
898
- if (!content)
899
- return null;
900
- if (content.identifier === identifier)
901
- return content;
902
- if (content.children) {
903
- for (const child of content.children) {
904
- const found = this.findContentInHierarchy(child, identifier);
905
- if (found)
906
- return found;
907
- }
908
- }
909
- return null;
910
- }
911
- get computedQueryParams() {
912
- if (this.isAllowed && !this.forPreview && this.isEnabled) {
913
- return {
914
- ...this.resourceLink.queryParams,
915
- preAssessment: 'true'
916
- };
917
- }
918
- return null;
919
- }
920
- get isMilestone() {
921
- if (this._cacheInitialized) {
922
- return this._cachedIsMilestone;
923
- }
924
- return this.computeIsMilestone();
925
- }
926
- getMilestoneCompletedCount() {
927
- if (!this.content || !this.hierarchyMapData) {
928
- return 0;
929
- }
930
- const milestoneData = this.hierarchyMapData[this.content.identifier];
931
- if (!milestoneData || !milestoneData.leafNodes) {
932
- return 0;
933
- }
934
- let completedCount = 0;
935
- milestoneData.leafNodes.forEach((leafId) => {
936
- const leafData = this.hierarchyMapData[leafId];
937
- if (leafData && leafData.completionStatus === 2) {
938
- completedCount++;
939
- }
940
- });
941
- return completedCount;
942
- }
943
- /**
944
- * Get unlock criteria message for locked milestones
945
- */
946
- getMilestoneUnlockMessage() {
947
- if (!this.content || !this.hierarchyMapData) {
948
- return '';
949
- }
950
- const milestoneData = this.hierarchyMapData[this.content.identifier];
951
- if (!milestoneData) {
952
- return '';
953
- }
954
- // Check if hashmap has pre-computed unlock message
955
- if (milestoneData.unlockMessage) {
956
- return milestoneData.unlockMessage;
957
- }
958
- const milestoneIndex = milestoneData.milestoneIndex;
959
- // Milestone 1 requires pre-assessment completion
960
- if (milestoneIndex === 0) {
961
- return 'Complete the preliminary assessment to unlock this milestone';
962
- }
963
- // Other milestones require previous milestone completion
964
- return `Complete all mandatory content and assessment in Milestone ${milestoneIndex} to unlock this milestone`;
965
- }
966
- /**
967
- * Get lock message for content inside locked milestones
968
- */
969
- getParentMilestoneLockMessage() {
970
- if (!this.isParentMilestoneLocked) {
971
- return '';
972
- }
973
- return 'This content is locked. Complete previous milestone to view this content.';
974
- }
975
- /**
976
- * Get lock message for milestone assessments
977
- */
978
- getAssessmentLockMessage() {
979
- if (!this.content || !this.hierarchyMapData) {
980
- return '';
981
- }
982
- const hashData = this.hierarchyMapData[this.content.identifier];
983
- // Check if hashmap has pre-computed assessment lock message
984
- if (hashData && hashData.assessmentLockMessage) {
985
- return hashData.assessmentLockMessage;
986
- }
987
- if (this.isMilestoneAssessmentLocked) {
988
- return 'This content is locked. Complete all mandatory items to unlock the assessment.';
989
- }
990
- return '';
991
- }
992
- shouldShowDownloadButton(content) {
993
- if (!content) {
994
- return false;
995
- }
996
- // Check if content has an artifact URL (downloadable resource)
997
- if (!content.artifactUrl) {
998
- return false;
999
- }
1000
- // Check if base content resource category includes "Case Study"
1001
- if (!this.baseContentReadData?.courseCategory ||
1002
- this.baseContentReadData.courseCategory !== NsContent.ECourseCategory.CASE_STUDY) {
1003
- return false;
1004
- }
1005
- //for public scenario check if its player plage then only enable download
1006
- if (this.forPreview && !window.location.href.includes('/viewer/')) {
1007
- return false;
1008
- }
1009
- // for logged in user check if user enrolled then only allow download
1010
- if (!this.forPreview && !this.isEnrolled) {
1011
- return false;
1012
- }
1013
- // Define downloadable MIME types
1014
- const downloadableMimeTypes = [
1015
- NsContent.EMimeTypes.PDF
1016
- ];
1017
- return downloadableMimeTypes.includes(content.mimeType);
1018
- }
1019
- downloadContent(content, event) {
1020
- if (event) {
1021
- event.preventDefault();
1022
- event.stopPropagation();
1023
- }
1024
- const pageId = `app/toc/pageId/${content.identifier}`;
1025
- this.resourceDownloadHelperSvc.downloadPDF(content, pageId);
1026
- console.log('content', content);
1027
- console.log('baseContent', this.baseContentReadData);
1028
- }
1029
- /**
1030
- * View milestone achievement - calls the achievement API and shows the result
1031
- */
1032
- viewMilestoneAchievement(event) {
1033
- if (event) {
1034
- event.preventDefault();
1035
- event.stopPropagation();
1036
- }
1037
- if (!this.content || !this.batchId || this.achievementLoading) {
1038
- return;
1039
- }
1040
- // Get user ID from ConfigurationsService
1041
- const userId = this.configSvc?.userProfile?.userId;
1042
- if (!userId) {
1043
- console.error('User ID not found');
1044
- return;
1045
- }
1046
- // Extract milestone ID (e.g., "m1", "m2") from the content name or index
1047
- // Try to get milestone number from the index or extract from content
1048
- let milestoneId = 'm' + (this.index - 1); // index is typically 1-based, milestones are 0-based
1049
- // If content name contains milestone number, extract it
1050
- if (this.content.name) {
1051
- const match = this.content.name.match(/milestone\s*(\d+)/i);
1052
- if (match) {
1053
- milestoneId = 'm' + match[1];
1054
- }
1055
- }
1056
- const courseId = this.baseContentReadData?.identifier || this.rootId;
1057
- this.achievementLoading = true;
1058
- this.appTocSvc.generateMilestoneAchievement(userId, courseId, this.batchId, milestoneId).subscribe({
1059
- next: (response) => {
1060
- this.achievementLoading = false;
1061
- console.log('Achievement generated successfully:', response);
1062
- // Show achievement dialog or handle response
1063
- if (response && response.result) {
1064
- // Open a dialog to show the achievement
1065
- this.dialog.open(CertificateDialogComponent, {
1066
- width: '1300px',
1067
- data: {
1068
- cet: response.result.printUri || response.result.svgData,
1069
- certId: response.result.identifier,
1070
- isAchievement: true
1071
- },
1072
- });
1073
- }
1074
- },
1075
- error: (error) => {
1076
- this.achievementLoading = false;
1077
- // Show error message in snackbar
1078
- const errorMessage = error?.error?.result?.message || error?.message || 'Failed to generate achievement';
1079
- this.snackBar.open(errorMessage, 'Close', {
1080
- duration: 5000,
1081
- horizontalPosition: 'center',
1082
- verticalPosition: 'bottom',
1083
- panelClass: ['error-snackbar']
1084
- });
1085
- console.error('Error generating achievement:', error);
1086
- }
1087
- });
1088
- }
1089
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AppTocContentCardV2Component, deps: [{ token: i1.EventService }, { token: i2.MatLegacyDialog }, { token: i0.Renderer2 }, { token: i3.CertificateService }, { token: i4.AppTocService }, { token: i5.ContentLanguageService }, { token: i6.ResourceDownloadHelperService }, { token: i1.ConfigurationsService }, { token: i7.MatLegacySnackBar }], target: i0.ɵɵFactoryTarget.Component }); }
1090
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: AppTocContentCardV2Component, selector: "ws-widget-app-toc-content-card-v2", inputs: { content: "content", expandAll: "expandAll", rootId: "rootId", rootContentType: "rootContentType", forPreview: "forPreview", batchId: "batchId", componentName: "componentName", index: "index", pathSet: "pathSet", expandActive: "expandActive", hierarchyMapData: "hierarchyMapData", batchData: "batchData", isPreAssessment: "isPreAssessment", baseContentReadData: "baseContentReadData", mlCourse: "mlCourse", parentMilestoneLocked: "parentMilestoneLocked" }, usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"content && !isPreAssessment\">\r\n <ng-container *ngIf=\"isCollection && !isModule\">\r\n <ng-container [ngTemplateOutlet]=\"collectionTemplate\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"isCollection && isModule\">\r\n <ng-container *ngIf=\"content?.moduleResourseCount\">\r\n <ng-container [ngTemplateOutlet]=\"collectionTemplate\">\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <div *ngIf=\"isResource\" class=\"resource-container\"\r\n [ngClass]=\"pathSet?.has(content?.identifier) && isEnrolled ? 'content-active-resource': 'content-not-active-resource'\">\r\n <div class=\"resource flex sm:flex-row flex-start width-expand w-100 sm:pr-4 sm:w-auto\"\r\n [ngClass]=\"{'activeResource': pathSet?.has(content?.identifier) && isEnrolled}\">\r\n <!-- Lock message for curated programs only (shown above content) -->\r\n <ng-container *ngIf=\"content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT && checkForCuratedProgram &&\r\n !isContentUnlocked\">\r\n <div class=\"content-locking flex w-full flex-middle mb-2 gap-3\">\r\n <mat-icon class=\"lock-icon\">lock</mat-icon>\r\n <span class=\"lock-message mat-body-2\">\r\n The content is locked. Complete program or all courses to view this module\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT && checkForCuratedProgram &&\r\n isContentUnlocked\">\r\n <div class=\"content-locking flex w-full flex-middle mb-2 gap-3\">\r\n <mat-icon class=\"unlock-icon\">lock_open_right</mat-icon>\r\n <span class=\"unlock-message mat-body-2\">\r\n This content is unlocked.\r\n </span>\r\n </div>\r\n </ng-container>\r\n <div class=\"flex flex-wrap items-start justify-start sm:justify-end\">\r\n <!-- <button *ngIf=\"!forPreview && content?.artifactUrl && !isXSmall && isAllowed && isEnabled\" type=\"button\"\r\n mat-icon-button class=\"\" [matMenuTriggerFor]=\"buttonMenu\">\r\n <mat-icon>more_vertical</mat-icon>\r\n </button> -->\r\n <ng-container *ngIf=\"isEnrolled && !isMilestoneLocked && !isParentMilestoneLocked\">\r\n <ng-container\r\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) ; else elseBlock\">\r\n\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) == 2\">\r\n <div class=\"completed\">\r\n <div>\r\n <mat-icon class=\"completed-icon\" [color]=\"blue\">check_circle</mat-icon>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\r\n <circle-progress class=\"flex items-center progress\"\r\n [percent]=\"getCompletionPercentage(content?.identifier)\" [radius]=\"10\"\r\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [space]=\"-2\"\r\n [outerStrokeColor]=\"progressColor2()\" [innerStrokeColor]=\"'rgba(0, 0, 0, 0.16)'\"\r\n [animation]=\"true\" [animationDuration]=\"250\" [showTitle]=\"false\" [showUnits]=\"false\"\r\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\r\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\" [backgroundStrokeWidth]=\"3\"\r\n matTooltip=\"In progress\" [showZeroOuterStroke]=false [backgroundPadding]=\"-9\"\r\n [startFromZero]=\"false\" [backgroundPadding]=\"0\" [imageHeight]=\"22\" [imageWidth]=\"22\"\r\n [showBackground]=\"false\" [outerStrokeLinecap]=\"'butt'\">\r\n </circle-progress>\r\n <!-- <ws-widget-content-progress *ngIf=\"content?.identifier\" [forPreview]=\"forPreview\"\r\n [contentId]=\"content?.identifier\" class=\"progress-bar-thin\" [progress]=\"content?.completionPercentage\"\r\n [progressType]=\"'percentage'\">\r\n </ws-widget-content-progress> -->\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #elseBlock>\r\n <circle-progress class=\"flex items-center progress\" [percent]=\"0\" [radius]=\"11\"\r\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [outerStrokeColor]=\"'#808080'\"\r\n [innerStrokeColor]=\"'#808080'\" [animation]=\"true\" [space]=\"-2\" [showUnits]=\"false\"\r\n [animationDuration]=\"250\" [showTitle]=\"false\" [backgroundPadding]=\"0\"\r\n [backgroundPadding]=\"-9\" [outerStrokeLinecap]=\"'butt'\" matTooltip=\"Not started\"\r\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\" [imageHeight]=\"22\"\r\n [imageWidth]=\"22\" [showBackground]=\"false\"></circle-progress>\r\n <!-- <p>no data</p> -->\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n <!-- deactivated as per NIC CEO requirement to access course wthout login -->\r\n <!-- For locked assessments: show content but make it non-clickable -->\r\n <div class=\"width-expand\" *ngIf=\"isMilestoneAssessmentLocked && isEnrolled; else clickableContent\"\r\n [ngClass]=\"{'ml-3': isEnrolled}\">\r\n <div class=\"text-truncate opacity-60\">\r\n <div class=\"flex flex-col sm:flex-row flex-wrap\">\r\n <div class=\"flex items-center gap-2 w-full\">\r\n <mat-icon class=\"text-gray-500\">lock</mat-icon>\r\n <p class=\"margin-remove text-truncate mat-body-2 flex-auto font-bold nodtranslate text-gray-600\">\r\n {{ content?.name | truncate:50 }}\r\n </p>\r\n </div>\r\n <span class=\"content-type optional-span nodtranslate\" *ngIf=\"content?.optionalReading\">{{\r\n 'playerbrief.optional' | translate | titlecase}} </span>\r\n </div>\r\n <!-- for default grey icons -->\r\n <ng-container *ngIf=\"!pathSet?.has(content?.identifier) || !isEnrolled\">\r\n <div class=\"resicons ws-mat-black60-text\">\r\n <img src=\"/assets/icons/content/grey/video.svg\" alt=\"Video\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\r\n content?.mimeType ==='application/x-mpegURL'\">\r\n <img src=\"/assets/icons/content/grey/audio.svg\" alt=\"Audio\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'audio/mpeg'\">\r\n <img src=\"/assets/icons/content/grey/pdf.svg\" alt=\"PDF\" class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/pdf'\">\r\n <img src=\"/assets/icons/content/grey/link.svg\" alt=\"InteractiveContent\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\r\n <img src=\"/assets/icons/content/grey/assessment.svg\" alt=\"Assessment\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\r\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\r\n <img src=\"/assets/icons/content/grey/content_copy.svg\" class=\"contenticon\" alt=\"Course\"\r\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\r\n <img src=\"/assets/icons/content/grey/module.svg\" class=\"float-left margin-right-xs\"\r\n alt=\"offline sessions\" *ngIf=\"content.mimeType === 'application/offline'\">\r\n\r\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ content?.maxQuestions\r\n }} {{ 'playerbrief.questions' | translate | titlecase}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ (content?.duration||\r\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\r\n pipeDurationTransform:\r\n 'hms'\r\n }}</span>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </div>\r\n \r\n <!-- Lock message displayed BELOW assessment details when locked -->\r\n <div class=\"content-locking flex w-full flex-middle mt-2 gap-2 px-2 py-1 bg-orange-50 border-l-4 border-orange-400\">\r\n <mat-icon class=\"lock-icon text-orange-600\" style=\"font-size: 18px; width: 18px; height: 18px;\">lock</mat-icon>\r\n <span class=\"lock-message mat-body-2 text-orange-800\" style=\"font-size: 13px;\">\r\n This content is locked. Complete all mandatory items to unlock the assessment.\r\n </span>\r\n </div>\r\n </div>\r\n \r\n <!-- Clickable content template (when NOT locked) -->\r\n <ng-template #clickableContent>\r\n <a class=\"width-expand\"\r\n [class.disabled]=\"(forPreview || !isEnabled || !isEnrolled || !isBatchInProgess || !isContentUnlocked || isParentMilestoneLocked) ? true : null\"\r\n [ngClass]=\"{'ml-3': isEnrolled}\"\r\n [routerLink]=\"(isAllowed && !forPreview && isEnabled && !isParentMilestoneLocked) ? resourceLink.url : null\"\r\n [queryParams]=\"(isAllowed && !forPreview && isEnabled && !isParentMilestoneLocked) ? resourceLink.queryParams : null\"\r\n [matTooltip]=\"isParentMilestoneLocked ? 'This content is locked. Complete previous milestone to view this content.' : ''\"\r\n matTooltipPosition=\"above\">\r\n <div [ngClass]=\"{'resource-active': pathSet?.has(content?.identifier) && isEnrolled}\"></div>\r\n <div class=\"text-truncate \" [ngClass]=\"{'cursor-pointer': !isEnabled && isEnrolled}\"\r\n (click)=\"content.viewChildren = !content.viewChildren; raiseTelemetry(); changeResource()\">\r\n <div class=\"flex flex-col sm:flex-row flex-wrap\">\r\n <p class=\"margin-remove text-truncate mat-body-2 flex-auto font-bold nodtranslate\"\r\n [ngClass]=\"{'text-active': pathSet?.has(content?.identifier) && isEnrolled}\">\r\n {{ content?.name | truncate:50 }}\r\n </p>\r\n <span class=\"content-type optional-span nodtranslate\" *ngIf=\"content?.optionalReading\">{{\r\n 'playerbrief.optional' | translate | titlecase}} </span>\r\n </div>\r\n <!-- for default grey icons -->\r\n <ng-container *ngIf=\"!pathSet?.has(content?.identifier) || !isEnrolled\">\r\n <div class=\"resicons ws-mat-black60-text\">\r\n <img src=\"/assets/icons/content/grey/video.svg\" alt=\"Video\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\r\n content?.mimeType ==='application/x-mpegURL'\">\r\n <img src=\"/assets/icons/content/grey/audio.svg\" alt=\"Audio\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'audio/mpeg'\">\r\n <img src=\"/assets/icons/content/grey/pdf.svg\" alt=\"PDF\" class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/pdf'\">\r\n <img src=\"/assets/icons/content/grey/link.svg\" alt=\"InteractiveContent\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\r\n <img src=\"/assets/icons/content/grey/assessment.svg\" alt=\"Assessment\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\r\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\r\n <img src=\"/assets/icons/content/grey/content_copy.svg\" class=\"contenticon\" alt=\"Course\"\r\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\r\n <img src=\"/assets/icons/content/grey/module.svg\" class=\"float-left margin-right-xs\"\r\n alt=\"offline sessions\" *ngIf=\"content.mimeType === 'application/offline'\">\r\n\r\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ content?.maxQuestions\r\n }} {{ 'playerbrief.questions' | translate | titlecase}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ (content?.duration||\r\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\r\n pipeDurationTransform:\r\n 'hms'\r\n }}</span>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- for white icons when content highlighted -->\r\n <ng-container *ngIf=\"pathSet?.has(content?.identifier) && isEnrolled\">\r\n <div class=\"resicons ws-mat-white-text\">\r\n <img src=\"/assets/icons/content/white/video.svg\" alt=\"Video\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\r\n content?.mimeType ==='application/x-mpegURL'\">\r\n <img src=\"/assets/icons/content/white/audio.svg\" alt=\"Audio\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'audio/mpeg'\">\r\n <img src=\"/assets/icons/content/white/pdf.svg\" alt=\"PDF\" class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/pdf'\">\r\n <img src=\"/assets/icons/content/white/link.svg\" alt=\"InteractiveContent\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\r\n <img src=\"/assets/icons/content/white/assessment.svg\" alt=\"Assessment\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\r\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\r\n <img src=\"/assets/icons/content/white/content_copy.svg\" class=\"contenticon\" alt=\"Course\"\r\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\r\n <img src=\"/assets/icons/content/white/module.svg\" class=\"float-left margin-right-xs\"\r\n alt=\"offline sessions\" *ngIf=\"content.mimeType === 'application/offline'\">\r\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ content?.maxQuestions\r\n }} {{ 'playerbrief.questions' | translate | titlecase}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ (content?.duration||\r\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\r\n pipeDurationTransform:\r\n 'hms'\r\n }}</span>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Download button for pdf resources -->\r\n <ng-container *ngIf=\"shouldShowDownloadButton(content)\">\r\n <div class=\"download-btn mat-body-2 mt-2 sm:mt-1\" (click)=\"downloadContent(content, $event)\"\r\n [ngClass]=\"{'active': pathSet?.has(content?.identifier)}\">\r\n <a class=\"download-link flex items-center\">\r\n <span class=\"\">Download</span>\r\n </a>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </a>\r\n </ng-template>\r\n </div>\r\n </div>\r\n</ng-container>\r\n\r\n<mat-menu #buttonMenu=\"matMenu\">\r\n <a mat-menu-item [routerLink]=\"'../' + content?.identifier + '/overview'\" [queryParams]=\"contextPath\"\r\n class=\"flex flex-middle\">\r\n <mat-icon>toc</mat-icon>\r\n <h3 class=\"margin-remove nodtranslate\">\r\n View Details\r\n </h3>\r\n </a>\r\n</mat-menu>\r\n\r\n<ng-template #collectionTemplate>\r\n <ng-container *ngIf=\"isCollection\">\r\n <div class=\"collection-wrapper p-4 flex flex-col position-relative\" [ngClass]=\"{'open': check(content),\r\n 'close': !content.viewChildren,\r\n 'course':!isModule, 'module': isModule,\r\n 'content-active': pathSet?.has(content.identifier) && isEnrolled}\">\r\n <div class=\"card-collection w-auto sm:w-100 padding-right-xl\">\r\n <!-- <img class=\"card-thumbnail ws-mat-primary-lite-background\" [src]=\"content?.appIcon\" alt=\"Thumbnail\"\r\n (click)=\"content.viewChildren = !content.viewChildren\" [wsUtilsDefaultThumbnail]=\"defaultThumbnail\" /> -->\r\n <div class=\"flex flex-col flex-wrap flex-between width-expand pr-0 w-100 \">\r\n <div class=\"text-truncate\" [ngClass]=\"{'cursor-pointer': !isEnabled}\"\r\n (click)=\"content.viewChildren = !content.viewChildren\">\r\n <div class=\"flex items-center justify-center mb-1 sm:flex-row\">\r\n <ng-container\r\n *ngIf=\"isModule && isEnrolled && !isMilestoneLocked && !isParentMilestoneLocked\">\r\n <ng-container\r\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) ; else elseBlock\">\r\n\r\n <ng-container *ngIf=\"getCompletionStatus(content.identifier) == 2\">\r\n <div class=\"completed mr-2\">\r\n <div>\r\n <mat-icon class=\"completed-icon\" [color]=\"blue\">check_circle</mat-icon>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\r\n <circle-progress class=\"flex items-center progress mr-1\"\r\n [percent]=\"getCompletionPercentage(content?.identifier)\" [radius]=\"10\"\r\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [space]=\"-2\"\r\n [outerStrokeColor]=\"progressColor2()\"\r\n [innerStrokeColor]=\"'rgba(0, 0, 0, 0.16)'\" [animation]=\"true\"\r\n [animationDuration]=\"250\" [showTitle]=\"false\" [showUnits]=\"false\"\r\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\r\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\"\r\n [backgroundStrokeWidth]=\"3\" matTooltip=\"In progress\"\r\n [showZeroOuterStroke]=false [backgroundPadding]=\"-7\" [startFromZero]=\"false\"\r\n [backgroundPadding]=\"0\" [imageHeight]=\"18\" [imageWidth]=\"18\"\r\n [showBackground]=\"false\" [outerStrokeLinecap]=\"'butt'\">\r\n </circle-progress>\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #elseBlock>\r\n <circle-progress class=\"flex items-center progress mr-1\" [percent]=\"0\" [radius]=\"11\"\r\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [outerStrokeColor]=\"'#808080'\"\r\n [innerStrokeColor]=\"'#808080'\" [animation]=\"true\" [space]=\"-2\"\r\n [showUnits]=\"false\" [animationDuration]=\"250\" [showTitle]=\"false\"\r\n [backgroundPadding]=\"0\" [backgroundPadding]=\"-9\" [outerStrokeLinecap]=\"'butt'\"\r\n matTooltip=\"Not started\" [showSubtitle]=\"false\" [showInnerStroke]=\"true\"\r\n [clockwise]=\"true\" [imageHeight]=\"22\" [imageWidth]=\"22\"\r\n [showBackground]=\"false\"></circle-progress>\r\n </ng-template>\r\n </ng-container>\r\n <div\r\n [ngClass]=\"{'collection-active-class': pathSet?.has(content?.identifier) && isEnrolled}\">\r\n </div>\r\n <img *ngIf=\"isMilestoneLocked\" src=\"assets/icons/hubs/lock.svg\" alt=\"Locked\"\r\n class=\"lock-icon mr-2 margin-bottom-xxs\">\r\n <p class=\"margin-remove text-truncate mat-subheading-1 flex-auto font-bold nodtranslate\"\r\n [ngClass]=\"{'text-active': pathSet?.has(content.identifier) && isEnrolled}\">\r\n <span>{{isMilestone ? index -1 : index}}. </span>{{ content?.name | truncate:50 }}\r\n <ng-container *ngIf=\"isMilestone\">\r\n <span *ngIf=\"isMilestoneLocked\" class=\"locked-text ml-2\">Locked</span>\r\n </ng-container>\r\n <span *ngIf=\"content?.isMandatory\"\r\n class=\"mandatory-text mat-caption ml-2\">Mandatory</span>\r\n </p>\r\n \r\n <div class=\"type-container resource mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Resource'\">\r\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\r\n <span class=\"nodtranslate\">Resource</span>\r\n </div>\r\n <div class=\"type-container module mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Collection'\">\r\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\r\n <span class=\"nodtranslate\">Module</span>\r\n </div>\r\n <div class=\"type-container course mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Course'\">\r\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\r\n <span class=\"nodtranslate\">Course</span>\r\n </div>\r\n </div>\r\n <!-- Milestone Badge -->\r\n <div *ngIf=\"isMilestone\" class=\"milestone-badge mt-2 mb-2\">\r\n <span class=\"milestone-badge-text nodtranslate\">Milestone {{index - 1}}</span>\r\n </div>\r\n <!-- Milestone Description (3 lines with ellipsis) -->\r\n <p *ngIf=\"isMilestone && content?.description\" class=\"milestone-description mt-2 nodtranslate\">\r\n {{ content?.description }}\r\n </p>\r\n <div class=\"flex flex-row gap-3 items-center content-key-values mt-2\">\r\n <mat-icon *ngIf=\"!isModule\" alt=\"course\"\r\n class=\"time-icon icon-color\">video_library</mat-icon>\r\n <img *ngIf=\"isModule\" alt=\"Module\" class=\"time-icon\"\r\n src=\"/assets/icons/content/grey/module.svg\">\r\n <div class=\"text-xs nodtranslate\">{{ (hierarchyMapData[content?.identifier]?.duration ||\r\n 120)|\r\n pipeDurationTransform: 'hms' }}</div>\r\n\r\n <ng-container *ngIf=\"content?.moduleCount\">\r\n <div class=\"flex items-center\">\r\n <span class=\"period\"></span>\r\n </div>\r\n <div class=\"text-xs nodtranslate\">{{content?.moduleCount}} {{content?.moduleCount > 1?\r\n 'modules' :\r\n 'module'}}</div>\r\n </ng-container>\r\n <ng-container *ngIf=\"content?.leafNodesCount\">\r\n <div class=\"flex items-center\">\r\n <span class=\"period\"></span>\r\n </div>\r\n <div class=\"text-xs nodtranslate\">{{content?.leafNodesCount}} {{content?.leafNodesCount\r\n >1 ? 'items':\r\n 'item'}}</div>\r\n </ng-container>\r\n </div>\r\n <!-- Milestone Completion Progress -->\r\n <div *ngIf=\"isMilestone && isEnrolled && !isMilestoneLocked\" class=\"milestone-progress mt-2 flex items-center justify-between\">\r\n <div>\r\n <span class=\"milestone-progress-text nodtranslate\">{{getMilestoneCompletedCount()}} of\r\n {{content?.leafNodesCount || 0}} completed</span>\r\n </div>\r\n <!-- View Achievement Button for completed milestones - Outside clickable area -->\r\n <div *ngIf=\"isMilestone && isEnrolled && (getCompletionPercentage(content?.identifier) >= 100 || getCompletionStatus(content?.identifier) === 2)\"\r\n class=\"view-achievement-container mt-2\">\r\n <button type=\"button\" class=\"view-achievement-btn\" [disabled]=\"achievementLoading\"\r\n (click)=\"viewMilestoneAchievement($event)\">\r\n <span *ngIf=\"!achievementLoading\">View Achievement</span>\r\n <mat-spinner *ngIf=\"achievementLoading\" [diameter]=\"16\" \r\n [strokeWidth]=\"2\" color=\"primary\" class=\"inline-spinner\"></mat-spinner>\r\n </button>\r\n </div>\r\n </div>\r\n <!-- Unlock Criteria Message for Locked Milestones -->\r\n <div *ngIf=\"isMilestone && isEnrolled && isMilestoneLocked\" class=\"milestone-locked-message mt-2\">\r\n <span class=\"locked-criteria-text mat-caption\">\r\n {{ getMilestoneUnlockMessage() }}\r\n </span>\r\n </div>\r\n \r\n </div>\r\n <!-- For course progress to be shown -->\r\n <ng-container *ngIf=\"isEnrolled && !isMilestoneLocked && !isParentMilestoneLocked\">\r\n <ng-container\r\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) && content.primaryCategory === 'Course'\">\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) == 2\">\r\n <div class=\"flex flex-1\">\r\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\r\n <div class=\"flex flex-row justify-end w-full \">\r\n <span class=\"mat-body-2 nodtranslate \">\r\n {{getCompletionPercentage(content?.identifier)}}%</span>\r\n </div>\r\n\r\n <ws-widget-content-progress [contentId]=\"content?.progress\"\r\n [progress]=\"getCompletionPercentage(content?.identifier)\"\r\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\r\n </ws-widget-content-progress>\r\n </div>\r\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\r\n <a class=\"ml-5 certificate-btn\"\r\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\r\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\r\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\r\n <span class=\"nodtranslate\">Certificate</span>\r\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\r\n class=\"ml-2\">arrow_downward</mat-icon>\r\n <div class=\"center flex flex-middle certificate-loader\"\r\n *ngIf=\"downloadCertificateLoading\">\r\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\r\n [diameter]=\"16\"></mat-spinner>\r\n </div>\r\n </a>\r\n </ng-container>\r\n </div>\r\n <!-- <circle-progress class=\"flex items-center progress\" [percent]=\"100\" [radius]=\"12\"\r\n [outerStrokeWidth]=\"3\" [innerStrokeWidth]=\"3\" [space]=\"-3\"\r\n [outerStrokeColor]=\"progressColor()\" [innerStrokeColor]=\"'rgba(0,0,0,.16)'\"\r\n [animation]=\"true\" [animationDuration]=\"300\" [showTitle]=\"false\" [showUnits]=\"false\"\r\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\r\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\" [backgroundStrokeWidth]=\"3\"\r\n [showZeroOuterStroke]=false [backgroundPadding]=\"-9\" [startFromZero]=\"false\"\r\n [backgroundPadding]=\"0\" [imageHeight]=\"24\" [imageWidth]=\"24\" [showBackground]=\"false\"\r\n [outerStrokeLinecap]=\"'butt'\">\r\n </circle-progress> -->\r\n </ng-container>\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\r\n <div class=\"flex flex-1\">\r\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\r\n <div class=\"flex flex-row justify-end w-full ws-mat-black-text\">\r\n <span class=\"mat-body-2 ws-mat-black-text nodtranslate\">\r\n {{getCompletionPercentage(content?.identifier)}}%</span>\r\n </div>\r\n\r\n <ws-widget-content-progress [contentId]=\"content?.progress\"\r\n [progress]=\"getCompletionPercentage(content?.identifier)\"\r\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\r\n </ws-widget-content-progress>\r\n </div>\r\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\r\n <a class=\"ml-5 certificate-btn\"\r\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\r\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\r\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\r\n <span class=\"nodtranslate\">Certificate</span>\r\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\r\n class=\"ml-2\">arrow_downward</mat-icon>\r\n <div class=\"center flex flex-middle certificate-loader\"\r\n *ngIf=\"downloadCertificateLoading\">\r\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\r\n [diameter]=\"16\"></mat-spinner>\r\n </div>\r\n </a>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <div class=\"see-all-container\">\r\n <a href=\"javascript:void(0)\" role=\"button\"\r\n (click)=\"content.viewChildren = !content.viewChildren; expandActive = false\"\r\n class=\"see-all-btn tab custom-chevron customicon\" mat-button>\r\n <mat-icon *ngIf=\"!content.viewChildren && !isModule\">keyboard_arrow_down</mat-icon>\r\n <mat-icon *ngIf=\"content.viewChildren && !isModule\">keyboard_arrow_up</mat-icon>\r\n <mat-icon *ngIf=\"!content.viewChildren && isModule\">add</mat-icon>\r\n <mat-icon *ngIf=\"content.viewChildren && isModule\">remove</mat-icon>\r\n </a>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"child-wrapper \" *ngIf=\"content.viewChildren\" [ngClass]=\"{'open': content.viewChildren,\r\n 'close': !content.viewChildren,\r\n 'course':!isModule,\r\n 'module': isModule}\" [@panelInOut]>\r\n <div class=\"children-container\" [ngClass]=\"{'module': isModule, '': !isModule}\">\r\n <ws-widget-app-toc-content-card-v2 [forPreview]=\"forPreview\" [componentName]=\"componentName\"\r\n [content]=\"child\" [expandAll]=\"expandAll\" [rootId]=\"rootId\" [batchId]=\"batchId\"\r\n [rootContentType]=\"rootContentType\" [index]=\"j+1\" [baseContentReadData]=\"baseContentReadData\"\r\n [pathSet]=\"pathSet\" [hierarchyMapData]=\"hierarchyMapData\" [batchData]=\"batchData\"\r\n [mlCourse]=\"mlCourse\" [parentMilestoneLocked]=\"isMilestoneLocked || isParentMilestoneLocked\"\r\n *ngFor=\"let child of content?.children; trackBy: contentTrackBy; let j= index;let isFirst = first\"\r\n [ngClass]=\"{'moduleCard': checkIsModule(child), 'resourceCard': !checkIsModule(child), 'first': isFirst}\">\r\n </ws-widget-app-toc-content-card-v2>\r\n </div>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n\r\n<ng-container *ngIf=\"isPreAssessment\">\r\n <div class=\"collection-wrapper p-4 flex flex-col position-relative\" [ngClass]=\"{'open': check(content),\r\n 'course':!isModule, 'module': isModule,\r\n 'content-active': pathSet?.has(content.identifier)}\">\r\n <div class=\"card-collection w-auto sm:w-100 padding-right-xl\">\r\n <!-- <img class=\"card-thumbnail ws-mat-primary-lite-background\" [src]=\"content?.appIcon\" alt=\"Thumbnail\"\r\n (click)=\"content.viewChildren = !content.viewChildren\" [wsUtilsDefaultThumbnail]=\"defaultThumbnail\" /> -->\r\n <div class=\"flex flex-col flex-wrap flex-between width-expand pr-0 w-100 \">\r\n\r\n <div class=\"text-truncate\" [ngClass]=\"{'cursor-pointer': !isEnabled}\"\r\n (click)=\"content.viewChildren = !content.viewChildren\">\r\n <div class=\"flex sm:flex-row flex-wrap\">\r\n <ng-container>\r\n <ng-container\r\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) ; else elseBlock\">\r\n\r\n <ng-container *ngIf=\"getCompletionStatus(content.identifier) == 2\">\r\n <div class=\"completed mr-2\">\r\n <div>\r\n <mat-icon class=\"completed-icon\" [color]=\"blue\">check_circle</mat-icon>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\r\n\r\n <circle-progress class=\"flex items-center progress mr-1\"\r\n [percent]=\"getCompletionPercentage(content?.identifier)\" [radius]=\"10\"\r\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [space]=\"-2\"\r\n [outerStrokeColor]=\"progressColor2()\" [innerStrokeColor]=\"'rgba(0, 0, 0, 0.16)'\"\r\n [animation]=\"true\" [animationDuration]=\"250\" [showTitle]=\"false\"\r\n [showUnits]=\"false\" [showSubtitle]=\"false\" [showInnerStroke]=\"true\"\r\n [clockwise]=\"true\" [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\"\r\n [backgroundStrokeWidth]=\"3\" matTooltip=\"In progress\" [showZeroOuterStroke]=false\r\n [backgroundPadding]=\"-7\" [startFromZero]=\"false\" [backgroundPadding]=\"0\"\r\n [imageHeight]=\"18\" [imageWidth]=\"18\" [showBackground]=\"false\"\r\n [outerStrokeLinecap]=\"'butt'\">\r\n </circle-progress>\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #elseBlock>\r\n <circle-progress class=\"flex items-center progress mr-1\" [percent]=\"0\" [radius]=\"11\"\r\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [outerStrokeColor]=\"'#808080'\"\r\n [innerStrokeColor]=\"'#808080'\" [animation]=\"true\" [space]=\"-2\" [showUnits]=\"false\"\r\n [animationDuration]=\"250\" [showTitle]=\"false\" [backgroundPadding]=\"0\"\r\n [backgroundPadding]=\"-9\" [outerStrokeLinecap]=\"'butt'\" matTooltip=\"Not started\"\r\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\r\n [imageHeight]=\"22\" [imageWidth]=\"22\" [showBackground]=\"false\"></circle-progress>\r\n </ng-template>\r\n </ng-container>\r\n <div [ngClass]=\"{'collection-active-class': pathSet?.has(content?.identifier)}\"></div>\r\n <!-- <p class=\"margin-remove text-truncate mat-subheading-1 flex-auto font-bold nodtranslate\"\r\n [ngClass]=\"{'text-active': pathSet?.has(content.identifier)}\">\r\n {{index}}. {{ content?.name | truncate:50 }}\r\n </p> -->\r\n <a class=\"margin-remove text-truncate mat-subheading-1 flex-auto font-bold nodtranslate\"\r\n [class.disabled]=\"null\" [ngClass]=\"{'ml-3': isEnrolled}\"\r\n [routerLink]=\"(isAllowed && !forPreview && isEnabled) ? resourceLink.url : null\"\r\n [queryParams]=\"computedQueryParams\">\r\n <!-- {{content?.courseCategory}} -->\r\n <div [ngClass]=\"{'resource-active': pathSet?.has(content?.identifier)}\"></div>\r\n <div class=\"text-truncate \" [ngClass]=\"{'cursor-pointer': !isEnabled}\"\r\n (click)=\"raiseTelemetry(); changeResource()\">\r\n <div class=\"flex flex-col sm:flex-row flex-wrap\">\r\n <p class=\"margin-remove text-truncate mat-body-2 flex-auto font-bold nodtranslate\"\r\n [ngClass]=\"{'text-active': pathSet?.has(content?.identifier)}\">\r\n <!-- <mat-icon class=\"margin-right-xs radiobtn time-icon\">radio_button_unchecked </mat-icon> -->\r\n {{index}}. {{ content?.name | truncate:50 }}\r\n\r\n </p>\r\n <span class=\"content-type optional-span nodtranslate\"\r\n *ngIf=\"content?.optionalReading\">{{ 'playerbrief.optional' | translate |\r\n titlecase}} </span>\r\n </div>\r\n <!-- for default grey icons -->\r\n <ng-container *ngIf=\"!pathSet?.has(content?.identifier)\">\r\n <div class=\"resicons ws-mat-black60-text\">\r\n <img src=\"/assets/icons/content/grey/video.svg\" alt=\"Video\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\r\n content?.mimeType ==='application/x-mpegURL'\">\r\n <img src=\"/assets/icons/content/grey/audio.svg\" alt=\"Audio\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'audio/mpeg'\">\r\n <img src=\"/assets/icons/content/grey/pdf.svg\" alt=\"PDF\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/pdf'\">\r\n <!-- <img src=\"/assets/icons/content/grey/resource.svg\" alt=\"Survey\" class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/survey'\"> -->\r\n <img src=\"/assets/icons/content/grey/link.svg\" alt=\"InteractiveContent\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\r\n <img src=\"/assets/icons/content/grey/assessment.svg\" alt=\"Assessment\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\r\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\r\n <img src=\"/assets/icons/content/grey/content_copy.svg\" class=\"contenticon\"\r\n alt=\"Course\"\r\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\r\n <img src=\"/assets/icons/content/grey/module.svg\"\r\n class=\"float-left margin-right-xs\" alt=\"offline sessions\"\r\n *ngIf=\"content.mimeType === 'application/offline'\">\r\n\r\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\r\n\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{\r\n content?.maxQuestions }} {{ 'playerbrief.questions' | translate |\r\n titlecase}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{\r\n (content?.duration||\r\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\r\n pipeDurationTransform:\r\n 'hms'\r\n }}</span>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- for white icons when content highlighted -->\r\n <ng-container *ngIf=\"pathSet?.has(content?.identifier)\">\r\n <div class=\"resicons ws-mat-white-text\">\r\n <img src=\"/assets/icons/content/white/video.svg\" alt=\"Video\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\r\n content?.mimeType ==='application/x-mpegURL'\">\r\n <img src=\"/assets/icons/content/white/audio.svg\" alt=\"Audio\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'audio/mpeg'\">\r\n <img src=\"/assets/icons/content/white/pdf.svg\" alt=\"PDF\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/pdf'\">\r\n <!-- <img src=\"/assets/icons/content/white/resource.svg\" alt=\"Survey\" class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/survey'\"> -->\r\n <img src=\"/assets/icons/content/white/link.svg\" alt=\"InteractiveContent\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\r\n <img src=\"/assets/icons/content/white/assessment.svg\" alt=\"Assessment\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\r\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\r\n <img src=\"/assets/icons/content/white/content_copy.svg\" class=\"contenticon\"\r\n alt=\"Course\"\r\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\r\n <img src=\"/assets/icons/content/white/module.svg\"\r\n class=\"float-left margin-right-xs\" alt=\"offline sessions\"\r\n *ngIf=\"content.mimeType === 'application/offline'\">\r\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\r\n <span class=\"resourceDuration ws-mat-white-text nodtranslate\">{{\r\n content?.maxQuestions }} {{ 'playerbrief.questions' | translate |\r\n titlecase}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\r\n <span class=\"resourceDuration ws-mat-white-text nodtranslate\">{{\r\n (content?.duration||\r\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\r\n pipeDurationTransform:\r\n 'hms'\r\n }}</span>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </a>\r\n <!-- <div class=\"type-container resource mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Resource'\">\r\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\r\n <span class=\"nodtranslate\">Resource</span>\r\n </div>\r\n <div class=\"type-container module mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Collection'\">\r\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\r\n <span class=\"nodtranslate\">Module</span>\r\n </div>\r\n <div class=\"type-container course mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Course'\">\r\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\r\n <span class=\"nodtranslate\">Course</span>\r\n </div> -->\r\n </div>\r\n\r\n </div>\r\n <!-- For course progress to be shown -->\r\n <ng-container>\r\n <ng-container\r\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier)\">\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) == 2\">\r\n <div class=\"flex flex-1\">\r\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\r\n <div class=\"flex flex-row justify-end w-full \">\r\n <span class=\"mat-body-2 nodtranslate \">\r\n {{getCompletionPercentage(content?.identifier)}}%</span>\r\n </div>\r\n\r\n <ws-widget-content-progress [contentId]=\"content?.progress\"\r\n [progress]=\"getCompletionPercentage(content?.identifier)\"\r\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\r\n </ws-widget-content-progress>\r\n </div>\r\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\r\n <a class=\"ml-5 certificate-btn\"\r\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\r\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\r\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\r\n <span class=\"nodtranslate\">Certificate</span>\r\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\r\n class=\"ml-2\">arrow_downward</mat-icon>\r\n <div class=\"center flex flex-middle certificate-loader\"\r\n *ngIf=\"downloadCertificateLoading\">\r\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\r\n [diameter]=\"16\"></mat-spinner>\r\n </div>\r\n </a>\r\n </ng-container>\r\n </div>\r\n <!-- <circle-progress class=\"flex items-center progress\" [percent]=\"100\" [radius]=\"12\"\r\n [outerStrokeWidth]=\"3\" [innerStrokeWidth]=\"3\" [space]=\"-3\"\r\n [outerStrokeColor]=\"progressColor()\" [innerStrokeColor]=\"'rgba(0,0,0,.16)'\"\r\n [animation]=\"true\" [animationDuration]=\"300\" [showTitle]=\"false\" [showUnits]=\"false\"\r\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\r\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\" [backgroundStrokeWidth]=\"3\"\r\n [showZeroOuterStroke]=false [backgroundPadding]=\"-9\" [startFromZero]=\"false\"\r\n [backgroundPadding]=\"0\" [imageHeight]=\"24\" [imageWidth]=\"24\" [showBackground]=\"false\"\r\n [outerStrokeLinecap]=\"'butt'\">\r\n </circle-progress> -->\r\n </ng-container>\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\r\n <div class=\"flex flex-1\">\r\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\r\n <div class=\"flex flex-row justify-end w-full ws-mat-black-text\">\r\n <span class=\"mat-body-2 ws-mat-black-text nodtranslate\">\r\n {{getCompletionPercentage(content?.identifier)}}%</span>\r\n </div>\r\n\r\n <ws-widget-content-progress [contentId]=\"content?.progress\"\r\n [progress]=\"getCompletionPercentage(content?.identifier)\"\r\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\r\n </ws-widget-content-progress>\r\n </div>\r\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\r\n <a class=\"ml-5 certificate-btn\"\r\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\r\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\r\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\r\n <span class=\"nodtranslate\">Certificate</span>\r\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\r\n class=\"ml-2\">arrow_downward</mat-icon>\r\n <div class=\"center flex flex-middle certificate-loader\"\r\n *ngIf=\"downloadCertificateLoading\">\r\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\r\n [diameter]=\"16\"></mat-spinner>\r\n </div>\r\n </a>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- <div class=\"see-all-container\">\r\n <a href=\"javascript:void(0)\" role=\"button\"\r\n (click)=\"content.viewChildren = !content.viewChildren; expandActive = false\"\r\n class=\"see-all-btn tab custom-chevron customicon\" mat-button>\r\n <mat-icon *ngIf=\"!content.viewChildren && !isModule\">keyboard_arrow_down</mat-icon>\r\n <mat-icon *ngIf=\"content.viewChildren && !isModule\">keyboard_arrow_up</mat-icon>\r\n <mat-icon *ngIf=\"!content.viewChildren && isModule\">add</mat-icon>\r\n <mat-icon *ngIf=\"content.viewChildren && isModule\">remove</mat-icon>\r\n </a>\r\n </div> -->\r\n </div>\r\n </div>\r\n </div>\r\n\r\n</ng-container>", styles: [".customicon{position:absolute;top:-.5em;right:0}.customicon .mat-icon{color:#1a4ca1}a.disabled{pointer-events:none;cursor:default}span.optional-span{margin-left:8px;padding:0 6px;border-radius:2px;display:inline-block;background-color:#0074b6;color:#fff;font-size:12px}.card-collection{display:flex;align-items:center;border-radius:8px}.card-collection .card-thumbnail{height:100%;margin-right:12px;cursor:pointer;border-radius:8px 0 0}@media only screen and (max-width: 469px){.card-collection{flex-direction:column;align-items:flex-start!important}.card-collection .card-thumbnail{height:100%!important;width:100%!important}.card-collection .text-truncate{white-space:unset!important}}.tab:focus{outline:1px solid!important}.custom-chevron:focus{outline:0px solid!important}.resource-container{display:flex;align-items:flex-start;flex-direction:column}.resource-container .resource{padding:16px 16px 16px 0;width:100%}.resource-container .card-thumbnail{height:100%;cursor:pointer}.resource-container .img-container{position:relative;margin-right:12px}.resource-container .img-container ws-widget-content-progress{position:absolute;left:0;right:0;bottom:5px}@media only screen and (max-width: 469px){.resource-container{flex-direction:column;align-items:flex-start!important}.resource-container .card-thumbnail{height:100%!important;width:100%!important}.resource-container .text-truncate{white-space:unset!important}}.child-meta-container{margin-top:8px;display:flex}.child-meta-container .child-structure{display:flex;align-items:center;flex-wrap:wrap}.child-meta-container .child-structure span{margin-right:12px;text-align:center;margin-bottom:8px}.child-meta-container .child-structure .structure-icon{margin-right:12px}@media only screen and (max-width: 469px){.child-meta-container{margin-left:.5rem;justify-content:space-between}}.resource-container{display:flex;align-items:center}.resource-container ws-display-content-type-icon{display:flex;align-items:center}.resource-container .resource-meta{margin-left:12px;display:flex;justify-content:space-between;align-items:center}.completed-icon{color:#1a4ca1}.collection-wrapper{padding:1rem}.collection-wrapper.course.content-active{background-color:#1a4ca1;color:#fff}.collection-wrapper.course.content-active .period{background:#fff}.collection-wrapper.course.content-active .text-active,.collection-wrapper.course.content-active .icon-color,.collection-wrapper.course.content-active .customicon .mat-icon{color:#fff}.collection-wrapper.course.content-active .progress-container span{color:#fff!important}.text-active{color:#1a4ca1}.text-active.font-bold{font-weight:600}.activeResource{background-color:#1a4ca1;color:#fff;padding-top:1rem!important;padding-bottom:1rem!important}.activeResource .text-active{color:#fff}.activeResource .text-active.font-bold{font-weight:600}.activeResource .resourceDuration,.activeResource .completed-icon{color:#fff}.collection-wrapper.open{border-bottom:1px solid rgba(0,0,0,.16)}.collection-wrapper.close{border:none}.child-wrapper.open{border-radius:0 0 8px 8px}.children-container .mat-subheading-1{font:500 16px/24px Lato!important}.children-container .resource-container{margin-bottom:16px}.children-container .resource-container .resource{padding:0}.children-container .resource-container .card-thumbnail{height:65px;align-self:center}.first.resourceCard:nth-child(1) .resource{margin-top:16px!important}.first.resourceCard:nth-child(1) .activeResource{margin-top:0!important}.children-container .resourceCard:last-child .resource-container:has(.activeResource){margin-bottom:0!important}.moduleCard:not(:last-child)>.collection-wrapper.close.module{border-bottom:4px solid rgba(0,0,0,.08);border-radius:0}.moduleCard:not(:last-child)>.collection-wrapper.open.module+.child-wrapper.open{border-bottom:4px solid rgba(0,0,0,.08);border-radius:0}.collection-wrapper.open.course+.child-wrapper.open .collection-wrapper.open.module+.child-wrapper.open{background-color:#eff3f9;border-bottom:4px solid rgba(0,0,0,.08);border-radius:0}.collection-wrapper.open.module+.child-wrapper.open{background-color:#eff3f9;border-radius:0;padding-bottom:8px}.content-heading{letter-spacing:0px;color:#222}.content-type{letter-spacing:0px}.time-icon{height:16px;width:16px;font-size:16px;vertical-align:middle}.time-icon.icon-color{color:#0009}.period{width:3px;height:3px;background:#0009;border-radius:4px}.time-value{letter-spacing:0px;color:#222;text-transform:lowercase}.see-all-container{position:absolute;right:16px;top:24px}.oval-white{background:#fff 0% 0% no-repeat padding-box;border-radius:8px;padding:2px 8px}.type-container{letter-spacing:0px;display:flex;align-items:center}.type-container .rotate-90{transform:rotate(-90deg)}.type-container .custom-icon{width:18px;height:18px;font-size:18px;margin-right:8px}.type-container.resource{color:#00a9f4}.type-container.module{color:#34d6a4}.type-container.course{color:#f58634}.no-mb{margin-bottom:0!important}.w-100{width:100%}.w-auto{width:auto}.progress-bar-thin{height:5px!important}.progress-bar-thin ::ng-deep .mat-progress-bar{height:5px}.progress-bar-thin ::ng-deep .theme-igot.day-mode .mat-progress-bar-buffer{background-color:transparent!important}.progress-bar-thin ::ng-deep .theme-igot.day-mode .mat-progress-bar-background{fill:transparent}.radiobtn{color:#00000029}.resicons img{width:22px;opacity:.5;margin-top:2px;vertical-align:sub}.certificate-btn{height:24px;background:#1a4ca1;display:flex;justify-content:center;align-items:center;padding:4px 11px;color:#fff;border-radius:20px;border:1px solid white;font:400 12px/16px Lato;cursor:pointer}.certificate-btn .mat-icon{fill:#fff;color:#fff;font-size:16px;height:auto;width:auto}.view-certificate-wrapper{display:flex;border-radius:4px;border:1.5px solid rgb(0,116,182);opacity:1;padding:8px}.collection-wrapper.course,.collection-wrapper.module,.resource-container .resource{padding-left:16px;box-sizing:border-box;width:100%;overflow:hidden}.children-container.module .resource-container .resource,.course .collection-wrapper.module{padding-left:24px;box-sizing:border-box;width:100%}.course .children-container.module .resource-container .resource{padding-left:32px;box-sizing:border-box;width:100%}.course .resource-container .resource{padding-left:24px}::ng-deep .white-spinner{stroke:#fff!important}.certificate-loader ::ng-deep .mat-progress-spinner circle,.mat-spinner circle{stroke:#fff}.lock-message{background:#fff4ec;color:#d13924;padding:10px;border-radius:4px;display:block!important;width:100%}.content-locking{padding:8px 12px;margin-top:8px;margin-left:0;margin-right:0;border-radius:4px;background:#fff4ec;display:flex!important;align-items:center;gap:8px;width:100%;box-sizing:border-box}.lock-icon{color:#f3962f;font-size:20px;flex-shrink:0}.unlock-message{background:#efffec;color:#0c9600;padding:10px}.unlock-icon{color:#0c9600}.download-btn{padding:4px 12px;text-underline-position:from-font;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none;cursor:pointer;border-radius:40px;color:#1b4ca1;font-weight:700;border:1px solid #1B4CA1;display:inline-block;pointer-events:auto;position:relative;z-index:1}.activeResource .download-btn.active{color:#fff;border:1px solid #fff}.milestone-badge{display:inline-block;background-color:#fefaf4;border:1px solid #EF951E;border-radius:16px;padding:2px 12px}.milestone-badge-text{font-size:12px;font-weight:500;color:#212121}.milestone-description{font-size:14px;line-height:1.5;color:#000000b3;margin:0;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}.milestone-progress{display:flex;align-items:center}.milestone-progress-text{font-size:14px;font-weight:500;color:#0009}.milestone-locked-message{display:flex;align-items:center;padding:8px 12px;background-color:#f3962f1a;border-left:3px solid #F3962F;border-radius:4px}.locked-criteria-text{font-size:13px;font-weight:400;color:#000000b3;line-height:1.4}.locked-text{font-size:14px;font-weight:500;color:#f3962f}.mandatory-text{color:#d13924!important}.view-achievement-container{display:flex;align-items:center}.view-achievement-btn{background-color:transparent;border:1.5px solid #1a4ca1;color:#1a4ca1;border-radius:20px;padding:6px 16px;font-size:14px;font-weight:500;cursor:pointer;display:flex;align-items:center;gap:8px;transition:all .2s ease;min-width:150px}.view-achievement-btn:hover:not(:disabled){background-color:#1a4ca1;color:#fff}.view-achievement-btn:disabled{opacity:.6;cursor:not-allowed}.view-achievement-btn .inline-spinner{display:inline-block}\n"], dependencies: [{ kind: "directive", type: i8.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i8.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i9.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i10.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i11.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i11.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "component", type: i12.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: i13.ContentProgressComponent, selector: "ws-widget-content-progress", inputs: ["contentId", "progress", "progressType", "forPreview", "className", "customClassName"] }, { kind: "component", type: i14.CircleProgressComponent, selector: "circle-progress", inputs: ["name", "class", "backgroundGradient", "backgroundColor", "backgroundGradientStopColor", "backgroundOpacity", "backgroundStroke", "backgroundStrokeWidth", "backgroundPadding", "radius", "space", "percent", "toFixed", "maxPercent", "renderOnClick", "units", "unitsFontSize", "unitsFontWeight", "unitsColor", "outerStrokeGradient", "outerStrokeWidth", "outerStrokeColor", "outerStrokeGradientStopColor", "outerStrokeLinecap", "innerStrokeColor", "innerStrokeWidth", "titleFormat", "title", "titleColor", "titleFontSize", "titleFontWeight", "subtitleFormat", "subtitle", "subtitleColor", "subtitleFontSize", "subtitleFontWeight", "imageSrc", "imageHeight", "imageWidth", "animation", "animateTitle", "animateSubtitle", "animationDuration", "showTitle", "showSubtitle", "showUnits", "showImage", "showBackground", "showInnerStroke", "clockwise", "responsive", "startFromZero", "showZeroOuterStroke", "lazy", "options"], outputs: ["onClick"] }, { kind: "directive", type: i15.MatLegacyTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: AppTocContentCardV2Component, selector: "ws-widget-app-toc-content-card-v2", inputs: ["content", "expandAll", "rootId", "rootContentType", "forPreview", "batchId", "componentName", "index", "pathSet", "expandActive", "hierarchyMapData", "batchData", "isPreAssessment", "baseContentReadData", "mlCourse", "parentMilestoneLocked"] }, { kind: "pipe", type: i8.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: i1.PipeDurationTransformPipe, name: "pipeDurationTransform" }, { kind: "pipe", type: i16.TranslatePipe, name: "translate" }, { kind: "pipe", type: i17.TruncatePipe, name: "truncate" }], animations: [
1091
- trigger('panelInOut', [
1092
- transition('void => *', [
1093
- style({ transform: 'translateY(-10%)', opacity: '0' }),
1094
- animate(250)
1095
- ]),
1096
- transition('* => void', [
1097
- animate(200, style({ transform: 'translateY(-10%)', opacity: '0' }))
1098
- ])
1099
- ])
1100
- ] }); }
1101
- }
1102
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AppTocContentCardV2Component, decorators: [{
1103
- type: Component,
1104
- args: [{ selector: 'ws-widget-app-toc-content-card-v2', animations: [
1105
- trigger('panelInOut', [
1106
- transition('void => *', [
1107
- style({ transform: 'translateY(-10%)', opacity: '0' }),
1108
- animate(250)
1109
- ]),
1110
- transition('* => void', [
1111
- animate(200, style({ transform: 'translateY(-10%)', opacity: '0' }))
1112
- ])
1113
- ])
1114
- ], template: "<ng-container *ngIf=\"content && !isPreAssessment\">\r\n <ng-container *ngIf=\"isCollection && !isModule\">\r\n <ng-container [ngTemplateOutlet]=\"collectionTemplate\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"isCollection && isModule\">\r\n <ng-container *ngIf=\"content?.moduleResourseCount\">\r\n <ng-container [ngTemplateOutlet]=\"collectionTemplate\">\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <div *ngIf=\"isResource\" class=\"resource-container\"\r\n [ngClass]=\"pathSet?.has(content?.identifier) && isEnrolled ? 'content-active-resource': 'content-not-active-resource'\">\r\n <div class=\"resource flex sm:flex-row flex-start width-expand w-100 sm:pr-4 sm:w-auto\"\r\n [ngClass]=\"{'activeResource': pathSet?.has(content?.identifier) && isEnrolled}\">\r\n <!-- Lock message for curated programs only (shown above content) -->\r\n <ng-container *ngIf=\"content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT && checkForCuratedProgram &&\r\n !isContentUnlocked\">\r\n <div class=\"content-locking flex w-full flex-middle mb-2 gap-3\">\r\n <mat-icon class=\"lock-icon\">lock</mat-icon>\r\n <span class=\"lock-message mat-body-2\">\r\n The content is locked. Complete program or all courses to view this module\r\n </span>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT && checkForCuratedProgram &&\r\n isContentUnlocked\">\r\n <div class=\"content-locking flex w-full flex-middle mb-2 gap-3\">\r\n <mat-icon class=\"unlock-icon\">lock_open_right</mat-icon>\r\n <span class=\"unlock-message mat-body-2\">\r\n This content is unlocked.\r\n </span>\r\n </div>\r\n </ng-container>\r\n <div class=\"flex flex-wrap items-start justify-start sm:justify-end\">\r\n <!-- <button *ngIf=\"!forPreview && content?.artifactUrl && !isXSmall && isAllowed && isEnabled\" type=\"button\"\r\n mat-icon-button class=\"\" [matMenuTriggerFor]=\"buttonMenu\">\r\n <mat-icon>more_vertical</mat-icon>\r\n </button> -->\r\n <ng-container *ngIf=\"isEnrolled && !isMilestoneLocked && !isParentMilestoneLocked\">\r\n <ng-container\r\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) ; else elseBlock\">\r\n\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) == 2\">\r\n <div class=\"completed\">\r\n <div>\r\n <mat-icon class=\"completed-icon\" [color]=\"blue\">check_circle</mat-icon>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\r\n <circle-progress class=\"flex items-center progress\"\r\n [percent]=\"getCompletionPercentage(content?.identifier)\" [radius]=\"10\"\r\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [space]=\"-2\"\r\n [outerStrokeColor]=\"progressColor2()\" [innerStrokeColor]=\"'rgba(0, 0, 0, 0.16)'\"\r\n [animation]=\"true\" [animationDuration]=\"250\" [showTitle]=\"false\" [showUnits]=\"false\"\r\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\r\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\" [backgroundStrokeWidth]=\"3\"\r\n matTooltip=\"In progress\" [showZeroOuterStroke]=false [backgroundPadding]=\"-9\"\r\n [startFromZero]=\"false\" [backgroundPadding]=\"0\" [imageHeight]=\"22\" [imageWidth]=\"22\"\r\n [showBackground]=\"false\" [outerStrokeLinecap]=\"'butt'\">\r\n </circle-progress>\r\n <!-- <ws-widget-content-progress *ngIf=\"content?.identifier\" [forPreview]=\"forPreview\"\r\n [contentId]=\"content?.identifier\" class=\"progress-bar-thin\" [progress]=\"content?.completionPercentage\"\r\n [progressType]=\"'percentage'\">\r\n </ws-widget-content-progress> -->\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #elseBlock>\r\n <circle-progress class=\"flex items-center progress\" [percent]=\"0\" [radius]=\"11\"\r\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [outerStrokeColor]=\"'#808080'\"\r\n [innerStrokeColor]=\"'#808080'\" [animation]=\"true\" [space]=\"-2\" [showUnits]=\"false\"\r\n [animationDuration]=\"250\" [showTitle]=\"false\" [backgroundPadding]=\"0\"\r\n [backgroundPadding]=\"-9\" [outerStrokeLinecap]=\"'butt'\" matTooltip=\"Not started\"\r\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\" [imageHeight]=\"22\"\r\n [imageWidth]=\"22\" [showBackground]=\"false\"></circle-progress>\r\n <!-- <p>no data</p> -->\r\n </ng-template>\r\n </ng-container>\r\n </div>\r\n <!-- deactivated as per NIC CEO requirement to access course wthout login -->\r\n <!-- For locked assessments: show content but make it non-clickable -->\r\n <div class=\"width-expand\" *ngIf=\"isMilestoneAssessmentLocked && isEnrolled; else clickableContent\"\r\n [ngClass]=\"{'ml-3': isEnrolled}\">\r\n <div class=\"text-truncate opacity-60\">\r\n <div class=\"flex flex-col sm:flex-row flex-wrap\">\r\n <div class=\"flex items-center gap-2 w-full\">\r\n <mat-icon class=\"text-gray-500\">lock</mat-icon>\r\n <p class=\"margin-remove text-truncate mat-body-2 flex-auto font-bold nodtranslate text-gray-600\">\r\n {{ content?.name | truncate:50 }}\r\n </p>\r\n </div>\r\n <span class=\"content-type optional-span nodtranslate\" *ngIf=\"content?.optionalReading\">{{\r\n 'playerbrief.optional' | translate | titlecase}} </span>\r\n </div>\r\n <!-- for default grey icons -->\r\n <ng-container *ngIf=\"!pathSet?.has(content?.identifier) || !isEnrolled\">\r\n <div class=\"resicons ws-mat-black60-text\">\r\n <img src=\"/assets/icons/content/grey/video.svg\" alt=\"Video\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\r\n content?.mimeType ==='application/x-mpegURL'\">\r\n <img src=\"/assets/icons/content/grey/audio.svg\" alt=\"Audio\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'audio/mpeg'\">\r\n <img src=\"/assets/icons/content/grey/pdf.svg\" alt=\"PDF\" class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/pdf'\">\r\n <img src=\"/assets/icons/content/grey/link.svg\" alt=\"InteractiveContent\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\r\n <img src=\"/assets/icons/content/grey/assessment.svg\" alt=\"Assessment\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\r\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\r\n <img src=\"/assets/icons/content/grey/content_copy.svg\" class=\"contenticon\" alt=\"Course\"\r\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\r\n <img src=\"/assets/icons/content/grey/module.svg\" class=\"float-left margin-right-xs\"\r\n alt=\"offline sessions\" *ngIf=\"content.mimeType === 'application/offline'\">\r\n\r\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ content?.maxQuestions\r\n }} {{ 'playerbrief.questions' | translate | titlecase}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ (content?.duration||\r\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\r\n pipeDurationTransform:\r\n 'hms'\r\n }}</span>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </div>\r\n \r\n <!-- Lock message displayed BELOW assessment details when locked -->\r\n <div class=\"content-locking flex w-full flex-middle mt-2 gap-2 px-2 py-1 bg-orange-50 border-l-4 border-orange-400\">\r\n <mat-icon class=\"lock-icon text-orange-600\" style=\"font-size: 18px; width: 18px; height: 18px;\">lock</mat-icon>\r\n <span class=\"lock-message mat-body-2 text-orange-800\" style=\"font-size: 13px;\">\r\n This content is locked. Complete all mandatory items to unlock the assessment.\r\n </span>\r\n </div>\r\n </div>\r\n \r\n <!-- Clickable content template (when NOT locked) -->\r\n <ng-template #clickableContent>\r\n <a class=\"width-expand\"\r\n [class.disabled]=\"(forPreview || !isEnabled || !isEnrolled || !isBatchInProgess || !isContentUnlocked || isParentMilestoneLocked) ? true : null\"\r\n [ngClass]=\"{'ml-3': isEnrolled}\"\r\n [routerLink]=\"(isAllowed && !forPreview && isEnabled && !isParentMilestoneLocked) ? resourceLink.url : null\"\r\n [queryParams]=\"(isAllowed && !forPreview && isEnabled && !isParentMilestoneLocked) ? resourceLink.queryParams : null\"\r\n [matTooltip]=\"isParentMilestoneLocked ? 'This content is locked. Complete previous milestone to view this content.' : ''\"\r\n matTooltipPosition=\"above\">\r\n <div [ngClass]=\"{'resource-active': pathSet?.has(content?.identifier) && isEnrolled}\"></div>\r\n <div class=\"text-truncate \" [ngClass]=\"{'cursor-pointer': !isEnabled && isEnrolled}\"\r\n (click)=\"content.viewChildren = !content.viewChildren; raiseTelemetry(); changeResource()\">\r\n <div class=\"flex flex-col sm:flex-row flex-wrap\">\r\n <p class=\"margin-remove text-truncate mat-body-2 flex-auto font-bold nodtranslate\"\r\n [ngClass]=\"{'text-active': pathSet?.has(content?.identifier) && isEnrolled}\">\r\n {{ content?.name | truncate:50 }}\r\n </p>\r\n <span class=\"content-type optional-span nodtranslate\" *ngIf=\"content?.optionalReading\">{{\r\n 'playerbrief.optional' | translate | titlecase}} </span>\r\n </div>\r\n <!-- for default grey icons -->\r\n <ng-container *ngIf=\"!pathSet?.has(content?.identifier) || !isEnrolled\">\r\n <div class=\"resicons ws-mat-black60-text\">\r\n <img src=\"/assets/icons/content/grey/video.svg\" alt=\"Video\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\r\n content?.mimeType ==='application/x-mpegURL'\">\r\n <img src=\"/assets/icons/content/grey/audio.svg\" alt=\"Audio\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'audio/mpeg'\">\r\n <img src=\"/assets/icons/content/grey/pdf.svg\" alt=\"PDF\" class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/pdf'\">\r\n <img src=\"/assets/icons/content/grey/link.svg\" alt=\"InteractiveContent\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\r\n <img src=\"/assets/icons/content/grey/assessment.svg\" alt=\"Assessment\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\r\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\r\n <img src=\"/assets/icons/content/grey/content_copy.svg\" class=\"contenticon\" alt=\"Course\"\r\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\r\n <img src=\"/assets/icons/content/grey/module.svg\" class=\"float-left margin-right-xs\"\r\n alt=\"offline sessions\" *ngIf=\"content.mimeType === 'application/offline'\">\r\n\r\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ content?.maxQuestions\r\n }} {{ 'playerbrief.questions' | translate | titlecase}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ (content?.duration||\r\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\r\n pipeDurationTransform:\r\n 'hms'\r\n }}</span>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- for white icons when content highlighted -->\r\n <ng-container *ngIf=\"pathSet?.has(content?.identifier) && isEnrolled\">\r\n <div class=\"resicons ws-mat-white-text\">\r\n <img src=\"/assets/icons/content/white/video.svg\" alt=\"Video\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\r\n content?.mimeType ==='application/x-mpegURL'\">\r\n <img src=\"/assets/icons/content/white/audio.svg\" alt=\"Audio\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'audio/mpeg'\">\r\n <img src=\"/assets/icons/content/white/pdf.svg\" alt=\"PDF\" class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/pdf'\">\r\n <img src=\"/assets/icons/content/white/link.svg\" alt=\"InteractiveContent\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\r\n <img src=\"/assets/icons/content/white/assessment.svg\" alt=\"Assessment\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\r\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\r\n <img src=\"/assets/icons/content/white/content_copy.svg\" class=\"contenticon\" alt=\"Course\"\r\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\r\n <img src=\"/assets/icons/content/white/module.svg\" class=\"float-left margin-right-xs\"\r\n alt=\"offline sessions\" *ngIf=\"content.mimeType === 'application/offline'\">\r\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ content?.maxQuestions\r\n }} {{ 'playerbrief.questions' | translate | titlecase}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ (content?.duration||\r\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\r\n pipeDurationTransform:\r\n 'hms'\r\n }}</span>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Download button for pdf resources -->\r\n <ng-container *ngIf=\"shouldShowDownloadButton(content)\">\r\n <div class=\"download-btn mat-body-2 mt-2 sm:mt-1\" (click)=\"downloadContent(content, $event)\"\r\n [ngClass]=\"{'active': pathSet?.has(content?.identifier)}\">\r\n <a class=\"download-link flex items-center\">\r\n <span class=\"\">Download</span>\r\n </a>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </a>\r\n </ng-template>\r\n </div>\r\n </div>\r\n</ng-container>\r\n\r\n<mat-menu #buttonMenu=\"matMenu\">\r\n <a mat-menu-item [routerLink]=\"'../' + content?.identifier + '/overview'\" [queryParams]=\"contextPath\"\r\n class=\"flex flex-middle\">\r\n <mat-icon>toc</mat-icon>\r\n <h3 class=\"margin-remove nodtranslate\">\r\n View Details\r\n </h3>\r\n </a>\r\n</mat-menu>\r\n\r\n<ng-template #collectionTemplate>\r\n <ng-container *ngIf=\"isCollection\">\r\n <div class=\"collection-wrapper p-4 flex flex-col position-relative\" [ngClass]=\"{'open': check(content),\r\n 'close': !content.viewChildren,\r\n 'course':!isModule, 'module': isModule,\r\n 'content-active': pathSet?.has(content.identifier) && isEnrolled}\">\r\n <div class=\"card-collection w-auto sm:w-100 padding-right-xl\">\r\n <!-- <img class=\"card-thumbnail ws-mat-primary-lite-background\" [src]=\"content?.appIcon\" alt=\"Thumbnail\"\r\n (click)=\"content.viewChildren = !content.viewChildren\" [wsUtilsDefaultThumbnail]=\"defaultThumbnail\" /> -->\r\n <div class=\"flex flex-col flex-wrap flex-between width-expand pr-0 w-100 \">\r\n <div class=\"text-truncate\" [ngClass]=\"{'cursor-pointer': !isEnabled}\"\r\n (click)=\"content.viewChildren = !content.viewChildren\">\r\n <div class=\"flex items-center justify-center mb-1 sm:flex-row\">\r\n <ng-container\r\n *ngIf=\"isModule && isEnrolled && !isMilestoneLocked && !isParentMilestoneLocked\">\r\n <ng-container\r\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) ; else elseBlock\">\r\n\r\n <ng-container *ngIf=\"getCompletionStatus(content.identifier) == 2\">\r\n <div class=\"completed mr-2\">\r\n <div>\r\n <mat-icon class=\"completed-icon\" [color]=\"blue\">check_circle</mat-icon>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\r\n <circle-progress class=\"flex items-center progress mr-1\"\r\n [percent]=\"getCompletionPercentage(content?.identifier)\" [radius]=\"10\"\r\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [space]=\"-2\"\r\n [outerStrokeColor]=\"progressColor2()\"\r\n [innerStrokeColor]=\"'rgba(0, 0, 0, 0.16)'\" [animation]=\"true\"\r\n [animationDuration]=\"250\" [showTitle]=\"false\" [showUnits]=\"false\"\r\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\r\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\"\r\n [backgroundStrokeWidth]=\"3\" matTooltip=\"In progress\"\r\n [showZeroOuterStroke]=false [backgroundPadding]=\"-7\" [startFromZero]=\"false\"\r\n [backgroundPadding]=\"0\" [imageHeight]=\"18\" [imageWidth]=\"18\"\r\n [showBackground]=\"false\" [outerStrokeLinecap]=\"'butt'\">\r\n </circle-progress>\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #elseBlock>\r\n <circle-progress class=\"flex items-center progress mr-1\" [percent]=\"0\" [radius]=\"11\"\r\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [outerStrokeColor]=\"'#808080'\"\r\n [innerStrokeColor]=\"'#808080'\" [animation]=\"true\" [space]=\"-2\"\r\n [showUnits]=\"false\" [animationDuration]=\"250\" [showTitle]=\"false\"\r\n [backgroundPadding]=\"0\" [backgroundPadding]=\"-9\" [outerStrokeLinecap]=\"'butt'\"\r\n matTooltip=\"Not started\" [showSubtitle]=\"false\" [showInnerStroke]=\"true\"\r\n [clockwise]=\"true\" [imageHeight]=\"22\" [imageWidth]=\"22\"\r\n [showBackground]=\"false\"></circle-progress>\r\n </ng-template>\r\n </ng-container>\r\n <div\r\n [ngClass]=\"{'collection-active-class': pathSet?.has(content?.identifier) && isEnrolled}\">\r\n </div>\r\n <img *ngIf=\"isMilestoneLocked\" src=\"assets/icons/hubs/lock.svg\" alt=\"Locked\"\r\n class=\"lock-icon mr-2 margin-bottom-xxs\">\r\n <p class=\"margin-remove text-truncate mat-subheading-1 flex-auto font-bold nodtranslate\"\r\n [ngClass]=\"{'text-active': pathSet?.has(content.identifier) && isEnrolled}\">\r\n <span>{{isMilestone ? index -1 : index}}. </span>{{ content?.name | truncate:50 }}\r\n <ng-container *ngIf=\"isMilestone\">\r\n <span *ngIf=\"isMilestoneLocked\" class=\"locked-text ml-2\">Locked</span>\r\n </ng-container>\r\n <span *ngIf=\"content?.isMandatory\"\r\n class=\"mandatory-text mat-caption ml-2\">Mandatory</span>\r\n </p>\r\n \r\n <div class=\"type-container resource mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Resource'\">\r\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\r\n <span class=\"nodtranslate\">Resource</span>\r\n </div>\r\n <div class=\"type-container module mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Collection'\">\r\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\r\n <span class=\"nodtranslate\">Module</span>\r\n </div>\r\n <div class=\"type-container course mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Course'\">\r\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\r\n <span class=\"nodtranslate\">Course</span>\r\n </div>\r\n </div>\r\n <!-- Milestone Badge -->\r\n <div *ngIf=\"isMilestone\" class=\"milestone-badge mt-2 mb-2\">\r\n <span class=\"milestone-badge-text nodtranslate\">Milestone {{index - 1}}</span>\r\n </div>\r\n <!-- Milestone Description (3 lines with ellipsis) -->\r\n <p *ngIf=\"isMilestone && content?.description\" class=\"milestone-description mt-2 nodtranslate\">\r\n {{ content?.description }}\r\n </p>\r\n <div class=\"flex flex-row gap-3 items-center content-key-values mt-2\">\r\n <mat-icon *ngIf=\"!isModule\" alt=\"course\"\r\n class=\"time-icon icon-color\">video_library</mat-icon>\r\n <img *ngIf=\"isModule\" alt=\"Module\" class=\"time-icon\"\r\n src=\"/assets/icons/content/grey/module.svg\">\r\n <div class=\"text-xs nodtranslate\">{{ (hierarchyMapData[content?.identifier]?.duration ||\r\n 120)|\r\n pipeDurationTransform: 'hms' }}</div>\r\n\r\n <ng-container *ngIf=\"content?.moduleCount\">\r\n <div class=\"flex items-center\">\r\n <span class=\"period\"></span>\r\n </div>\r\n <div class=\"text-xs nodtranslate\">{{content?.moduleCount}} {{content?.moduleCount > 1?\r\n 'modules' :\r\n 'module'}}</div>\r\n </ng-container>\r\n <ng-container *ngIf=\"content?.leafNodesCount\">\r\n <div class=\"flex items-center\">\r\n <span class=\"period\"></span>\r\n </div>\r\n <div class=\"text-xs nodtranslate\">{{content?.leafNodesCount}} {{content?.leafNodesCount\r\n >1 ? 'items':\r\n 'item'}}</div>\r\n </ng-container>\r\n </div>\r\n <!-- Milestone Completion Progress -->\r\n <div *ngIf=\"isMilestone && isEnrolled && !isMilestoneLocked\" class=\"milestone-progress mt-2 flex items-center justify-between\">\r\n <div>\r\n <span class=\"milestone-progress-text nodtranslate\">{{getMilestoneCompletedCount()}} of\r\n {{content?.leafNodesCount || 0}} completed</span>\r\n </div>\r\n <!-- View Achievement Button for completed milestones - Outside clickable area -->\r\n <div *ngIf=\"isMilestone && isEnrolled && (getCompletionPercentage(content?.identifier) >= 100 || getCompletionStatus(content?.identifier) === 2)\"\r\n class=\"view-achievement-container mt-2\">\r\n <button type=\"button\" class=\"view-achievement-btn\" [disabled]=\"achievementLoading\"\r\n (click)=\"viewMilestoneAchievement($event)\">\r\n <span *ngIf=\"!achievementLoading\">View Achievement</span>\r\n <mat-spinner *ngIf=\"achievementLoading\" [diameter]=\"16\" \r\n [strokeWidth]=\"2\" color=\"primary\" class=\"inline-spinner\"></mat-spinner>\r\n </button>\r\n </div>\r\n </div>\r\n <!-- Unlock Criteria Message for Locked Milestones -->\r\n <div *ngIf=\"isMilestone && isEnrolled && isMilestoneLocked\" class=\"milestone-locked-message mt-2\">\r\n <span class=\"locked-criteria-text mat-caption\">\r\n {{ getMilestoneUnlockMessage() }}\r\n </span>\r\n </div>\r\n \r\n </div>\r\n <!-- For course progress to be shown -->\r\n <ng-container *ngIf=\"isEnrolled && !isMilestoneLocked && !isParentMilestoneLocked\">\r\n <ng-container\r\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) && content.primaryCategory === 'Course'\">\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) == 2\">\r\n <div class=\"flex flex-1\">\r\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\r\n <div class=\"flex flex-row justify-end w-full \">\r\n <span class=\"mat-body-2 nodtranslate \">\r\n {{getCompletionPercentage(content?.identifier)}}%</span>\r\n </div>\r\n\r\n <ws-widget-content-progress [contentId]=\"content?.progress\"\r\n [progress]=\"getCompletionPercentage(content?.identifier)\"\r\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\r\n </ws-widget-content-progress>\r\n </div>\r\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\r\n <a class=\"ml-5 certificate-btn\"\r\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\r\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\r\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\r\n <span class=\"nodtranslate\">Certificate</span>\r\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\r\n class=\"ml-2\">arrow_downward</mat-icon>\r\n <div class=\"center flex flex-middle certificate-loader\"\r\n *ngIf=\"downloadCertificateLoading\">\r\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\r\n [diameter]=\"16\"></mat-spinner>\r\n </div>\r\n </a>\r\n </ng-container>\r\n </div>\r\n <!-- <circle-progress class=\"flex items-center progress\" [percent]=\"100\" [radius]=\"12\"\r\n [outerStrokeWidth]=\"3\" [innerStrokeWidth]=\"3\" [space]=\"-3\"\r\n [outerStrokeColor]=\"progressColor()\" [innerStrokeColor]=\"'rgba(0,0,0,.16)'\"\r\n [animation]=\"true\" [animationDuration]=\"300\" [showTitle]=\"false\" [showUnits]=\"false\"\r\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\r\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\" [backgroundStrokeWidth]=\"3\"\r\n [showZeroOuterStroke]=false [backgroundPadding]=\"-9\" [startFromZero]=\"false\"\r\n [backgroundPadding]=\"0\" [imageHeight]=\"24\" [imageWidth]=\"24\" [showBackground]=\"false\"\r\n [outerStrokeLinecap]=\"'butt'\">\r\n </circle-progress> -->\r\n </ng-container>\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\r\n <div class=\"flex flex-1\">\r\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\r\n <div class=\"flex flex-row justify-end w-full ws-mat-black-text\">\r\n <span class=\"mat-body-2 ws-mat-black-text nodtranslate\">\r\n {{getCompletionPercentage(content?.identifier)}}%</span>\r\n </div>\r\n\r\n <ws-widget-content-progress [contentId]=\"content?.progress\"\r\n [progress]=\"getCompletionPercentage(content?.identifier)\"\r\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\r\n </ws-widget-content-progress>\r\n </div>\r\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\r\n <a class=\"ml-5 certificate-btn\"\r\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\r\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\r\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\r\n <span class=\"nodtranslate\">Certificate</span>\r\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\r\n class=\"ml-2\">arrow_downward</mat-icon>\r\n <div class=\"center flex flex-middle certificate-loader\"\r\n *ngIf=\"downloadCertificateLoading\">\r\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\r\n [diameter]=\"16\"></mat-spinner>\r\n </div>\r\n </a>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <div class=\"see-all-container\">\r\n <a href=\"javascript:void(0)\" role=\"button\"\r\n (click)=\"content.viewChildren = !content.viewChildren; expandActive = false\"\r\n class=\"see-all-btn tab custom-chevron customicon\" mat-button>\r\n <mat-icon *ngIf=\"!content.viewChildren && !isModule\">keyboard_arrow_down</mat-icon>\r\n <mat-icon *ngIf=\"content.viewChildren && !isModule\">keyboard_arrow_up</mat-icon>\r\n <mat-icon *ngIf=\"!content.viewChildren && isModule\">add</mat-icon>\r\n <mat-icon *ngIf=\"content.viewChildren && isModule\">remove</mat-icon>\r\n </a>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"child-wrapper \" *ngIf=\"content.viewChildren\" [ngClass]=\"{'open': content.viewChildren,\r\n 'close': !content.viewChildren,\r\n 'course':!isModule,\r\n 'module': isModule}\" [@panelInOut]>\r\n <div class=\"children-container\" [ngClass]=\"{'module': isModule, '': !isModule}\">\r\n <ws-widget-app-toc-content-card-v2 [forPreview]=\"forPreview\" [componentName]=\"componentName\"\r\n [content]=\"child\" [expandAll]=\"expandAll\" [rootId]=\"rootId\" [batchId]=\"batchId\"\r\n [rootContentType]=\"rootContentType\" [index]=\"j+1\" [baseContentReadData]=\"baseContentReadData\"\r\n [pathSet]=\"pathSet\" [hierarchyMapData]=\"hierarchyMapData\" [batchData]=\"batchData\"\r\n [mlCourse]=\"mlCourse\" [parentMilestoneLocked]=\"isMilestoneLocked || isParentMilestoneLocked\"\r\n *ngFor=\"let child of content?.children; trackBy: contentTrackBy; let j= index;let isFirst = first\"\r\n [ngClass]=\"{'moduleCard': checkIsModule(child), 'resourceCard': !checkIsModule(child), 'first': isFirst}\">\r\n </ws-widget-app-toc-content-card-v2>\r\n </div>\r\n </div>\r\n </ng-container>\r\n</ng-template>\r\n\r\n\r\n<ng-container *ngIf=\"isPreAssessment\">\r\n <div class=\"collection-wrapper p-4 flex flex-col position-relative\" [ngClass]=\"{'open': check(content),\r\n 'course':!isModule, 'module': isModule,\r\n 'content-active': pathSet?.has(content.identifier)}\">\r\n <div class=\"card-collection w-auto sm:w-100 padding-right-xl\">\r\n <!-- <img class=\"card-thumbnail ws-mat-primary-lite-background\" [src]=\"content?.appIcon\" alt=\"Thumbnail\"\r\n (click)=\"content.viewChildren = !content.viewChildren\" [wsUtilsDefaultThumbnail]=\"defaultThumbnail\" /> -->\r\n <div class=\"flex flex-col flex-wrap flex-between width-expand pr-0 w-100 \">\r\n\r\n <div class=\"text-truncate\" [ngClass]=\"{'cursor-pointer': !isEnabled}\"\r\n (click)=\"content.viewChildren = !content.viewChildren\">\r\n <div class=\"flex sm:flex-row flex-wrap\">\r\n <ng-container>\r\n <ng-container\r\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) ; else elseBlock\">\r\n\r\n <ng-container *ngIf=\"getCompletionStatus(content.identifier) == 2\">\r\n <div class=\"completed mr-2\">\r\n <div>\r\n <mat-icon class=\"completed-icon\" [color]=\"blue\">check_circle</mat-icon>\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\r\n\r\n <circle-progress class=\"flex items-center progress mr-1\"\r\n [percent]=\"getCompletionPercentage(content?.identifier)\" [radius]=\"10\"\r\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [space]=\"-2\"\r\n [outerStrokeColor]=\"progressColor2()\" [innerStrokeColor]=\"'rgba(0, 0, 0, 0.16)'\"\r\n [animation]=\"true\" [animationDuration]=\"250\" [showTitle]=\"false\"\r\n [showUnits]=\"false\" [showSubtitle]=\"false\" [showInnerStroke]=\"true\"\r\n [clockwise]=\"true\" [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\"\r\n [backgroundStrokeWidth]=\"3\" matTooltip=\"In progress\" [showZeroOuterStroke]=false\r\n [backgroundPadding]=\"-7\" [startFromZero]=\"false\" [backgroundPadding]=\"0\"\r\n [imageHeight]=\"18\" [imageWidth]=\"18\" [showBackground]=\"false\"\r\n [outerStrokeLinecap]=\"'butt'\">\r\n </circle-progress>\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #elseBlock>\r\n <circle-progress class=\"flex items-center progress mr-1\" [percent]=\"0\" [radius]=\"11\"\r\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [outerStrokeColor]=\"'#808080'\"\r\n [innerStrokeColor]=\"'#808080'\" [animation]=\"true\" [space]=\"-2\" [showUnits]=\"false\"\r\n [animationDuration]=\"250\" [showTitle]=\"false\" [backgroundPadding]=\"0\"\r\n [backgroundPadding]=\"-9\" [outerStrokeLinecap]=\"'butt'\" matTooltip=\"Not started\"\r\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\r\n [imageHeight]=\"22\" [imageWidth]=\"22\" [showBackground]=\"false\"></circle-progress>\r\n </ng-template>\r\n </ng-container>\r\n <div [ngClass]=\"{'collection-active-class': pathSet?.has(content?.identifier)}\"></div>\r\n <!-- <p class=\"margin-remove text-truncate mat-subheading-1 flex-auto font-bold nodtranslate\"\r\n [ngClass]=\"{'text-active': pathSet?.has(content.identifier)}\">\r\n {{index}}. {{ content?.name | truncate:50 }}\r\n </p> -->\r\n <a class=\"margin-remove text-truncate mat-subheading-1 flex-auto font-bold nodtranslate\"\r\n [class.disabled]=\"null\" [ngClass]=\"{'ml-3': isEnrolled}\"\r\n [routerLink]=\"(isAllowed && !forPreview && isEnabled) ? resourceLink.url : null\"\r\n [queryParams]=\"computedQueryParams\">\r\n <!-- {{content?.courseCategory}} -->\r\n <div [ngClass]=\"{'resource-active': pathSet?.has(content?.identifier)}\"></div>\r\n <div class=\"text-truncate \" [ngClass]=\"{'cursor-pointer': !isEnabled}\"\r\n (click)=\"raiseTelemetry(); changeResource()\">\r\n <div class=\"flex flex-col sm:flex-row flex-wrap\">\r\n <p class=\"margin-remove text-truncate mat-body-2 flex-auto font-bold nodtranslate\"\r\n [ngClass]=\"{'text-active': pathSet?.has(content?.identifier)}\">\r\n <!-- <mat-icon class=\"margin-right-xs radiobtn time-icon\">radio_button_unchecked </mat-icon> -->\r\n {{index}}. {{ content?.name | truncate:50 }}\r\n\r\n </p>\r\n <span class=\"content-type optional-span nodtranslate\"\r\n *ngIf=\"content?.optionalReading\">{{ 'playerbrief.optional' | translate |\r\n titlecase}} </span>\r\n </div>\r\n <!-- for default grey icons -->\r\n <ng-container *ngIf=\"!pathSet?.has(content?.identifier)\">\r\n <div class=\"resicons ws-mat-black60-text\">\r\n <img src=\"/assets/icons/content/grey/video.svg\" alt=\"Video\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\r\n content?.mimeType ==='application/x-mpegURL'\">\r\n <img src=\"/assets/icons/content/grey/audio.svg\" alt=\"Audio\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'audio/mpeg'\">\r\n <img src=\"/assets/icons/content/grey/pdf.svg\" alt=\"PDF\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/pdf'\">\r\n <!-- <img src=\"/assets/icons/content/grey/resource.svg\" alt=\"Survey\" class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/survey'\"> -->\r\n <img src=\"/assets/icons/content/grey/link.svg\" alt=\"InteractiveContent\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\r\n <img src=\"/assets/icons/content/grey/assessment.svg\" alt=\"Assessment\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\r\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\r\n <img src=\"/assets/icons/content/grey/content_copy.svg\" class=\"contenticon\"\r\n alt=\"Course\"\r\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\r\n <img src=\"/assets/icons/content/grey/module.svg\"\r\n class=\"float-left margin-right-xs\" alt=\"offline sessions\"\r\n *ngIf=\"content.mimeType === 'application/offline'\">\r\n\r\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\r\n\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{\r\n content?.maxQuestions }} {{ 'playerbrief.questions' | translate |\r\n titlecase}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\r\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{\r\n (content?.duration||\r\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\r\n pipeDurationTransform:\r\n 'hms'\r\n }}</span>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- for white icons when content highlighted -->\r\n <ng-container *ngIf=\"pathSet?.has(content?.identifier)\">\r\n <div class=\"resicons ws-mat-white-text\">\r\n <img src=\"/assets/icons/content/white/video.svg\" alt=\"Video\"\r\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\r\n content?.mimeType ==='application/x-mpegURL'\">\r\n <img src=\"/assets/icons/content/white/audio.svg\" alt=\"Audio\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'audio/mpeg'\">\r\n <img src=\"/assets/icons/content/white/pdf.svg\" alt=\"PDF\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/pdf'\">\r\n <!-- <img src=\"/assets/icons/content/white/resource.svg\" alt=\"Survey\" class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/survey'\"> -->\r\n <img src=\"/assets/icons/content/white/link.svg\" alt=\"InteractiveContent\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\r\n <img src=\"/assets/icons/content/white/assessment.svg\" alt=\"Assessment\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\r\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\r\n class=\"float-left margin-right-xs\"\r\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\r\n <img src=\"/assets/icons/content/white/content_copy.svg\" class=\"contenticon\"\r\n alt=\"Course\"\r\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\r\n <img src=\"/assets/icons/content/white/module.svg\"\r\n class=\"float-left margin-right-xs\" alt=\"offline sessions\"\r\n *ngIf=\"content.mimeType === 'application/offline'\">\r\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\r\n <span class=\"resourceDuration ws-mat-white-text nodtranslate\">{{\r\n content?.maxQuestions }} {{ 'playerbrief.questions' | translate |\r\n titlecase}}</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\r\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\r\n <span class=\"resourceDuration ws-mat-white-text nodtranslate\">{{\r\n (content?.duration||\r\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\r\n pipeDurationTransform:\r\n 'hms'\r\n }}</span>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </a>\r\n <!-- <div class=\"type-container resource mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Resource'\">\r\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\r\n <span class=\"nodtranslate\">Resource</span>\r\n </div>\r\n <div class=\"type-container module mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Collection'\">\r\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\r\n <span class=\"nodtranslate\">Module</span>\r\n </div>\r\n <div class=\"type-container course mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Course'\">\r\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\r\n <span class=\"nodtranslate\">Course</span>\r\n </div> -->\r\n </div>\r\n\r\n </div>\r\n <!-- For course progress to be shown -->\r\n <ng-container>\r\n <ng-container\r\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier)\">\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) == 2\">\r\n <div class=\"flex flex-1\">\r\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\r\n <div class=\"flex flex-row justify-end w-full \">\r\n <span class=\"mat-body-2 nodtranslate \">\r\n {{getCompletionPercentage(content?.identifier)}}%</span>\r\n </div>\r\n\r\n <ws-widget-content-progress [contentId]=\"content?.progress\"\r\n [progress]=\"getCompletionPercentage(content?.identifier)\"\r\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\r\n </ws-widget-content-progress>\r\n </div>\r\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\r\n <a class=\"ml-5 certificate-btn\"\r\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\r\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\r\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\r\n <span class=\"nodtranslate\">Certificate</span>\r\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\r\n class=\"ml-2\">arrow_downward</mat-icon>\r\n <div class=\"center flex flex-middle certificate-loader\"\r\n *ngIf=\"downloadCertificateLoading\">\r\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\r\n [diameter]=\"16\"></mat-spinner>\r\n </div>\r\n </a>\r\n </ng-container>\r\n </div>\r\n <!-- <circle-progress class=\"flex items-center progress\" [percent]=\"100\" [radius]=\"12\"\r\n [outerStrokeWidth]=\"3\" [innerStrokeWidth]=\"3\" [space]=\"-3\"\r\n [outerStrokeColor]=\"progressColor()\" [innerStrokeColor]=\"'rgba(0,0,0,.16)'\"\r\n [animation]=\"true\" [animationDuration]=\"300\" [showTitle]=\"false\" [showUnits]=\"false\"\r\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\r\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\" [backgroundStrokeWidth]=\"3\"\r\n [showZeroOuterStroke]=false [backgroundPadding]=\"-9\" [startFromZero]=\"false\"\r\n [backgroundPadding]=\"0\" [imageHeight]=\"24\" [imageWidth]=\"24\" [showBackground]=\"false\"\r\n [outerStrokeLinecap]=\"'butt'\">\r\n </circle-progress> -->\r\n </ng-container>\r\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\r\n <div class=\"flex flex-1\">\r\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\r\n <div class=\"flex flex-row justify-end w-full ws-mat-black-text\">\r\n <span class=\"mat-body-2 ws-mat-black-text nodtranslate\">\r\n {{getCompletionPercentage(content?.identifier)}}%</span>\r\n </div>\r\n\r\n <ws-widget-content-progress [contentId]=\"content?.progress\"\r\n [progress]=\"getCompletionPercentage(content?.identifier)\"\r\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\r\n </ws-widget-content-progress>\r\n </div>\r\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\r\n <a class=\"ml-5 certificate-btn\"\r\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\r\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\r\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\r\n <span class=\"nodtranslate\">Certificate</span>\r\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\r\n class=\"ml-2\">arrow_downward</mat-icon>\r\n <div class=\"center flex flex-middle certificate-loader\"\r\n *ngIf=\"downloadCertificateLoading\">\r\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\r\n [diameter]=\"16\"></mat-spinner>\r\n </div>\r\n </a>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- <div class=\"see-all-container\">\r\n <a href=\"javascript:void(0)\" role=\"button\"\r\n (click)=\"content.viewChildren = !content.viewChildren; expandActive = false\"\r\n class=\"see-all-btn tab custom-chevron customicon\" mat-button>\r\n <mat-icon *ngIf=\"!content.viewChildren && !isModule\">keyboard_arrow_down</mat-icon>\r\n <mat-icon *ngIf=\"content.viewChildren && !isModule\">keyboard_arrow_up</mat-icon>\r\n <mat-icon *ngIf=\"!content.viewChildren && isModule\">add</mat-icon>\r\n <mat-icon *ngIf=\"content.viewChildren && isModule\">remove</mat-icon>\r\n </a>\r\n </div> -->\r\n </div>\r\n </div>\r\n </div>\r\n\r\n</ng-container>", styles: [".customicon{position:absolute;top:-.5em;right:0}.customicon .mat-icon{color:#1a4ca1}a.disabled{pointer-events:none;cursor:default}span.optional-span{margin-left:8px;padding:0 6px;border-radius:2px;display:inline-block;background-color:#0074b6;color:#fff;font-size:12px}.card-collection{display:flex;align-items:center;border-radius:8px}.card-collection .card-thumbnail{height:100%;margin-right:12px;cursor:pointer;border-radius:8px 0 0}@media only screen and (max-width: 469px){.card-collection{flex-direction:column;align-items:flex-start!important}.card-collection .card-thumbnail{height:100%!important;width:100%!important}.card-collection .text-truncate{white-space:unset!important}}.tab:focus{outline:1px solid!important}.custom-chevron:focus{outline:0px solid!important}.resource-container{display:flex;align-items:flex-start;flex-direction:column}.resource-container .resource{padding:16px 16px 16px 0;width:100%}.resource-container .card-thumbnail{height:100%;cursor:pointer}.resource-container .img-container{position:relative;margin-right:12px}.resource-container .img-container ws-widget-content-progress{position:absolute;left:0;right:0;bottom:5px}@media only screen and (max-width: 469px){.resource-container{flex-direction:column;align-items:flex-start!important}.resource-container .card-thumbnail{height:100%!important;width:100%!important}.resource-container .text-truncate{white-space:unset!important}}.child-meta-container{margin-top:8px;display:flex}.child-meta-container .child-structure{display:flex;align-items:center;flex-wrap:wrap}.child-meta-container .child-structure span{margin-right:12px;text-align:center;margin-bottom:8px}.child-meta-container .child-structure .structure-icon{margin-right:12px}@media only screen and (max-width: 469px){.child-meta-container{margin-left:.5rem;justify-content:space-between}}.resource-container{display:flex;align-items:center}.resource-container ws-display-content-type-icon{display:flex;align-items:center}.resource-container .resource-meta{margin-left:12px;display:flex;justify-content:space-between;align-items:center}.completed-icon{color:#1a4ca1}.collection-wrapper{padding:1rem}.collection-wrapper.course.content-active{background-color:#1a4ca1;color:#fff}.collection-wrapper.course.content-active .period{background:#fff}.collection-wrapper.course.content-active .text-active,.collection-wrapper.course.content-active .icon-color,.collection-wrapper.course.content-active .customicon .mat-icon{color:#fff}.collection-wrapper.course.content-active .progress-container span{color:#fff!important}.text-active{color:#1a4ca1}.text-active.font-bold{font-weight:600}.activeResource{background-color:#1a4ca1;color:#fff;padding-top:1rem!important;padding-bottom:1rem!important}.activeResource .text-active{color:#fff}.activeResource .text-active.font-bold{font-weight:600}.activeResource .resourceDuration,.activeResource .completed-icon{color:#fff}.collection-wrapper.open{border-bottom:1px solid rgba(0,0,0,.16)}.collection-wrapper.close{border:none}.child-wrapper.open{border-radius:0 0 8px 8px}.children-container .mat-subheading-1{font:500 16px/24px Lato!important}.children-container .resource-container{margin-bottom:16px}.children-container .resource-container .resource{padding:0}.children-container .resource-container .card-thumbnail{height:65px;align-self:center}.first.resourceCard:nth-child(1) .resource{margin-top:16px!important}.first.resourceCard:nth-child(1) .activeResource{margin-top:0!important}.children-container .resourceCard:last-child .resource-container:has(.activeResource){margin-bottom:0!important}.moduleCard:not(:last-child)>.collection-wrapper.close.module{border-bottom:4px solid rgba(0,0,0,.08);border-radius:0}.moduleCard:not(:last-child)>.collection-wrapper.open.module+.child-wrapper.open{border-bottom:4px solid rgba(0,0,0,.08);border-radius:0}.collection-wrapper.open.course+.child-wrapper.open .collection-wrapper.open.module+.child-wrapper.open{background-color:#eff3f9;border-bottom:4px solid rgba(0,0,0,.08);border-radius:0}.collection-wrapper.open.module+.child-wrapper.open{background-color:#eff3f9;border-radius:0;padding-bottom:8px}.content-heading{letter-spacing:0px;color:#222}.content-type{letter-spacing:0px}.time-icon{height:16px;width:16px;font-size:16px;vertical-align:middle}.time-icon.icon-color{color:#0009}.period{width:3px;height:3px;background:#0009;border-radius:4px}.time-value{letter-spacing:0px;color:#222;text-transform:lowercase}.see-all-container{position:absolute;right:16px;top:24px}.oval-white{background:#fff 0% 0% no-repeat padding-box;border-radius:8px;padding:2px 8px}.type-container{letter-spacing:0px;display:flex;align-items:center}.type-container .rotate-90{transform:rotate(-90deg)}.type-container .custom-icon{width:18px;height:18px;font-size:18px;margin-right:8px}.type-container.resource{color:#00a9f4}.type-container.module{color:#34d6a4}.type-container.course{color:#f58634}.no-mb{margin-bottom:0!important}.w-100{width:100%}.w-auto{width:auto}.progress-bar-thin{height:5px!important}.progress-bar-thin ::ng-deep .mat-progress-bar{height:5px}.progress-bar-thin ::ng-deep .theme-igot.day-mode .mat-progress-bar-buffer{background-color:transparent!important}.progress-bar-thin ::ng-deep .theme-igot.day-mode .mat-progress-bar-background{fill:transparent}.radiobtn{color:#00000029}.resicons img{width:22px;opacity:.5;margin-top:2px;vertical-align:sub}.certificate-btn{height:24px;background:#1a4ca1;display:flex;justify-content:center;align-items:center;padding:4px 11px;color:#fff;border-radius:20px;border:1px solid white;font:400 12px/16px Lato;cursor:pointer}.certificate-btn .mat-icon{fill:#fff;color:#fff;font-size:16px;height:auto;width:auto}.view-certificate-wrapper{display:flex;border-radius:4px;border:1.5px solid rgb(0,116,182);opacity:1;padding:8px}.collection-wrapper.course,.collection-wrapper.module,.resource-container .resource{padding-left:16px;box-sizing:border-box;width:100%;overflow:hidden}.children-container.module .resource-container .resource,.course .collection-wrapper.module{padding-left:24px;box-sizing:border-box;width:100%}.course .children-container.module .resource-container .resource{padding-left:32px;box-sizing:border-box;width:100%}.course .resource-container .resource{padding-left:24px}::ng-deep .white-spinner{stroke:#fff!important}.certificate-loader ::ng-deep .mat-progress-spinner circle,.mat-spinner circle{stroke:#fff}.lock-message{background:#fff4ec;color:#d13924;padding:10px;border-radius:4px;display:block!important;width:100%}.content-locking{padding:8px 12px;margin-top:8px;margin-left:0;margin-right:0;border-radius:4px;background:#fff4ec;display:flex!important;align-items:center;gap:8px;width:100%;box-sizing:border-box}.lock-icon{color:#f3962f;font-size:20px;flex-shrink:0}.unlock-message{background:#efffec;color:#0c9600;padding:10px}.unlock-icon{color:#0c9600}.download-btn{padding:4px 12px;text-underline-position:from-font;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none;cursor:pointer;border-radius:40px;color:#1b4ca1;font-weight:700;border:1px solid #1B4CA1;display:inline-block;pointer-events:auto;position:relative;z-index:1}.activeResource .download-btn.active{color:#fff;border:1px solid #fff}.milestone-badge{display:inline-block;background-color:#fefaf4;border:1px solid #EF951E;border-radius:16px;padding:2px 12px}.milestone-badge-text{font-size:12px;font-weight:500;color:#212121}.milestone-description{font-size:14px;line-height:1.5;color:#000000b3;margin:0;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}.milestone-progress{display:flex;align-items:center}.milestone-progress-text{font-size:14px;font-weight:500;color:#0009}.milestone-locked-message{display:flex;align-items:center;padding:8px 12px;background-color:#f3962f1a;border-left:3px solid #F3962F;border-radius:4px}.locked-criteria-text{font-size:13px;font-weight:400;color:#000000b3;line-height:1.4}.locked-text{font-size:14px;font-weight:500;color:#f3962f}.mandatory-text{color:#d13924!important}.view-achievement-container{display:flex;align-items:center}.view-achievement-btn{background-color:transparent;border:1.5px solid #1a4ca1;color:#1a4ca1;border-radius:20px;padding:6px 16px;font-size:14px;font-weight:500;cursor:pointer;display:flex;align-items:center;gap:8px;transition:all .2s ease;min-width:150px}.view-achievement-btn:hover:not(:disabled){background-color:#1a4ca1;color:#fff}.view-achievement-btn:disabled{opacity:.6;cursor:not-allowed}.view-achievement-btn .inline-spinner{display:inline-block}\n"] }]
1115
- }], ctorParameters: function () { return [{ type: i1.EventService }, { type: i2.MatLegacyDialog }, { type: i0.Renderer2 }, { type: i3.CertificateService }, { type: i4.AppTocService }, { type: i5.ContentLanguageService }, { type: i6.ResourceDownloadHelperService }, { type: i1.ConfigurationsService }, { type: i7.MatLegacySnackBar }]; }, propDecorators: { content: [{
1116
- type: Input
1117
- }], expandAll: [{
1118
- type: Input
1119
- }], rootId: [{
1120
- type: Input
1121
- }], rootContentType: [{
1122
- type: Input
1123
- }], forPreview: [{
1124
- type: Input
1125
- }], batchId: [{
1126
- type: Input
1127
- }], componentName: [{
1128
- type: Input
1129
- }], index: [{
1130
- type: Input
1131
- }], pathSet: [{
1132
- type: Input
1133
- }], expandActive: [{
1134
- type: Input
1135
- }], hierarchyMapData: [{
1136
- type: Input
1137
- }], batchData: [{
1138
- type: Input
1139
- }], isPreAssessment: [{
1140
- type: Input
1141
- }], baseContentReadData: [{
1142
- type: Input
1143
- }], mlCourse: [{
1144
- type: Input
1145
- }], parentMilestoneLocked: [{
1146
- type: Input
1147
- }] } });
1148
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLXRvYy1jb250ZW50LWNhcmQtdjIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicmFyeS9zdW5iaXJkLWNiL3RvYy9zcmMvbGliL19jb2xsZWN0aW9uL19jb21tb24vY29udGVudC10b2MvYXBwLXRvYy1jb250ZW50LWNhcmQtdjIvYXBwLXRvYy1jb250ZW50LWNhcmQtdjIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicmFyeS9zdW5iaXJkLWNiL3RvYy9zcmMvbGliL19jb2xsZWN0aW9uL19jb21tb24vY29udGVudC10b2MvYXBwLXRvYy1jb250ZW50LWNhcmQtdjIvYXBwLXRvYy1jb250ZW50LWNhcmQtdjIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQW9DLE1BQU0sZUFBZSxDQUFBO0FBQ2xGLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQTtBQUN0RSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQTtBQUU5RSxPQUFPLEVBQWdCLFFBQVEsRUFBeUIsTUFBTSxzQkFBc0IsQ0FBQTtBQUNwRixPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSx1REFBdUQsQ0FBQTtBQUVsRyxPQUFPLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUE7QUFDekUsbUJBQW1CO0FBQ25CLE9BQU8sQ0FBQyxNQUFNLFFBQVEsQ0FBQTtBQUN0QixPQUFPLE1BQU0sTUFBTSxRQUFRLENBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUF3QjNCLE1BQU0sT0FBTyw0QkFBNEI7SUEyRHZDLFlBQ1UsTUFBb0IsRUFDcEIsTUFBaUIsRUFDakIsUUFBbUIsRUFDbkIsa0JBQXNDLEVBQ3RDLFNB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QkFDSDsyV0FHUSxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLG1CQUFtQjtzQkFBM0IsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLHFCQUFxQjtzQkFBN0IsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE9uSW5pdCwgUmVuZGVyZXIyLCBTaW1wbGVDaGFuZ2VzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSdcclxuaW1wb3J0IHsgTnNDb250ZW50IH0gZnJvbSAnLi4vLi4vLi4vLi4vX3NlcnZpY2VzL3dpZGdldC1jb250ZW50Lm1vZGVsJ1xyXG5pbXBvcnQgeyB2aWV3ZXJSb3V0ZUdlbmVyYXRvciB9IGZyb20gJy4uLy4uLy4uLy4uL19zZXJ2aWNlcy92aWV3ZXItcm91dGUtdXRpbCdcclxuaW1wb3J0IHsgTnNBcHBUb2MgfSBmcm9tICcuLi8uLi8uLi8uLi9tb2RlbHMvYXBwLXRvYy5tb2RlbCdcclxuaW1wb3J0IHsgRXZlbnRTZXJ2aWNlLCBXc0V2ZW50cywgQ29uZmlndXJhdGlvbnNTZXJ2aWNlIH0gZnJvbSAnQHN1bmJpcmQtY2IvdXRpbHMtdjInXHJcbmltcG9ydCB7IENlcnRpZmljYXRlRGlhbG9nQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vY2VydGlmaWNhdGUtZGlhbG9nL2NlcnRpZmljYXRlLWRpYWxvZy5jb21wb25lbnQnXHJcbmltcG9ydCB7IE1hdExlZ2FjeURpYWxvZyBhcyBNYXREaWFsb2cgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9sZWdhY3ktZGlhbG9nJ1xyXG5pbXBvcnQgeyBhbmltYXRlLCBzdHlsZSwgdHJhbnNpdGlvbiwgdHJpZ2dlciB9IGZyb20gJ0Bhbmd1bGFyL2FuaW1hdGlvbnMnXHJcbi8qIHRzbGludDpkaXNhYmxlKi9cclxuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJ1xyXG5pbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudCdcclxuaW1wb3J0IHsgQ2VydGlmaWNhdGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vLi4vc2VydmljZXMvY2VydGlmaWNhdGUuc2VydmljZSdcclxuaW1wb3J0IHsgQXBwVG9jU2VydmljZSB9IGZyb20gJy4uLy4uLy4uLy4uL3NlcnZpY2VzL2FwcC10b2Muc2VydmljZSdcclxuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcydcclxuaW1wb3J0IHsgQ29udGVudExhbmd1YWdlU2VydmljZSB9IGZyb20gJ0BzdW5iaXJkLWNiL2NvbnN1bXB0aW9uJ1xyXG5pbXBvcnQgeyBSZXNvdXJjZURvd25sb2FkSGVscGVyU2VydmljZSB9IGZyb20gJy4uLy4uLy4uLy4uL3NlcnZpY2VzL3Jlc291cmNlLWRvd25sb2FkLWhlbHBlci5zZXJ2aWNlJ1xyXG5pbXBvcnQgeyBNYXRMZWdhY3lTbmFja0JhciBhcyBNYXRTbmFja0JhciB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2xlZ2FjeS1zbmFjay1iYXInXHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ3dzLXdpZGdldC1hcHAtdG9jLWNvbnRlbnQtY2FyZC12MicsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2FwcC10b2MtY29udGVudC1jYXJkLXYyLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9hcHAtdG9jLWNvbnRlbnQtY2FyZC12Mi5jb21wb25lbnQuc2NzcyddLFxyXG4gIGFuaW1hdGlvbnM6IFtcclxuICAgIHRyaWdnZXIoJ3BhbmVsSW5PdXQnLCBbXHJcbiAgICAgIHRyYW5zaXRpb24oJ3ZvaWQgPT4gKicsIFtcclxuICAgICAgICBzdHlsZSh7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVkoLTEwJSknLCBvcGFjaXR5OiAnMCcgfSksXHJcbiAgICAgICAgYW5pbWF0ZSgyNTApXHJcbiAgICAgIF0pLFxyXG4gICAgICB0cmFuc2l0aW9uKCcqID0+IHZvaWQnLCBbXHJcbiAgICAgICAgYW5pbWF0ZSgyMDAsIHN0eWxlKHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlWSgtMTAlKScsIG9wYWNpdHk6ICcwJyB9KSlcclxuICAgICAgXSlcclxuICAgIF0pXHJcbiAgXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgQXBwVG9jQ29udGVudENhcmRWMkNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcbiAgQElucHV0KCkgY29udGVudDogTnNDb250ZW50LklDb250ZW50IHwgbnVsbCA9IG51bGxcclxuICBASW5wdXQoKSBleHBhbmRBbGwgPSBmYWxzZVxyXG4gIEBJbnB1dCgpIHJvb3RJZCE6IHN0cmluZ1xyXG4gIEBJbnB1dCgpIHJvb3RDb250ZW50VHlwZSE6IHN0cmluZ1xyXG4gIEBJbnB1dCgpIGZvclByZXZpZXcgPSBmYWxzZVxyXG4gIEBJbnB1dCgpIGJhdGNoSWQhOiBzdHJpbmdcclxuICBASW5wdXQoKSBjb21wb25lbnROYW1lOiBzdHJpbmcgPSAndG9jJ1xyXG4gIEBJbnB1dCgpIGluZGV4ITogbnVtYmVyXHJcbiAgQElucHV0KCkgcGF0aFNldCE6IGFueVxyXG4gIEBJbnB1dCgpIGV4cGFuZEFjdGl2ZSA9IHRydWVcclxuICBASW5wdXQoKSBoaWVyYXJjaHlNYXBEYXRhOiBhbnkgPSB7fVxyXG4gIEBJbnB1dCgpIGJhdGNoRGF0YTogLyoqTnNDb250ZW50LklCYXRjaExpc3RSZXNwb25zZSAqLyBhbnkgfCBudWxsID0gbnVsbFxyXG4gIEBJbnB1dCgpIGlzUHJlQXNzZXNzbWVudCA9IGZhbHNlXHJcbiAgQElucHV0KCkgYmFzZUNvbnRlbnRSZWFkRGF0YTogTnNDb250ZW50LklDb250ZW50IHwgbnVsbCA9IG51bGxcclxuICBASW5wdXQoKSBtbENvdXJzZTogTnNDb250ZW50LklDb250ZW50IHwgbnVsbCA9IG51bGxcclxuICBASW5wdXQoKSBwYXJlbnRNaWxlc3RvbmVMb2NrZWQgPSBmYWxzZSAvLyBQYXNzZWQgZnJvbSBwYXJlbnQgd2hlbiBpbnNpZGUgYSBsb2NrZWQgbWlsZXN0b25lXHJcbiAgaGFzQ29udGVudFN0cnVjdHVyZSA9IGZhbHNlXHJcbiAgZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmcgPSBmYWxzZVxyXG4gIGVudW1Db250ZW50VHlwZXMgPSBOc0NvbnRlbnQuRURpc3BsYXlDb250ZW50VHlwZXNcclxuICBjb250ZW50U3RydWN0dXJlOiBOc0FwcFRvYy5JVG9jU3RydWN0dXJlID0ge1xyXG4gICAgYXNzZXNzbWVudDogMCxcclxuICAgIGZpbmFsVGVzdDogMCxcclxuICAgIGNvdXJzZTogMCxcclxuICAgIGhhbmRzT246IDAsXHJcbiAgICBpbnRlcmFjdGl2ZVZpZGVvOiAwLFxyXG4gICAgbGVhcm5pbmdNb2R1bGU6IDAsXHJcbiAgICBvdGhlcjogMCxcclxuICAgIHBkZjogMCxcclxuICAgIHN1cnZleTogMCxcclxuICAgIHBvZGNhc3Q6IDAsXHJcbiAgICBwcmFjdGljZVRlc3Q6IDAsXHJcbiAgICBxdWl6OiAwLFxyXG4gICAgdmlkZW86IDAsXHJcbiAgICB3ZWJNb2R1bGU6IDAsXHJcbiAgICB3ZWJQYWdlOiAwLFxyXG4gICAgeW91dHViZTogMCxcclxuICAgIGludGVyYWN0aXZlY29udGVudDogMCxcclxuICAgIG9mZmxpbmVTZXNzaW9uOiAwLFxyXG4gIH1cclxuICBkZWZhdWx0VGh1bWJuYWlsID0gJydcclxuICB2aWV3Q2hpbGRyZW4gPSBmYWxzZVxyXG4gIHByaW1hcnlDYXRlZ29yeSA9IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5XHJcbiAgcGFnZVNjcm9sbFN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uIHwgbnVsbCA9IG51bGxcclxuICBhY2hpZXZlbWVudExvYWRpbmc6IGJvb2xlYW4gPSBmYWxzZVxyXG4gIC8vIENhY2hlZCBjb21wdXRlZCBwcm9wZXJ0aWVzIGZvciBwZXJmb3JtYW5jZSBvcHRpbWl6YXRpb25cclxuICBwcml2YXRlIF9jYWNoZWRJc0NvbGxlY3Rpb246IGJvb2xlYW4gPSBmYWxzZVxyXG4gIHByaXZhdGUgX2NhY2hlZElzTW9kdWxlOiBib29sZWFuID0gZmFsc2VcclxuICBwcml2YXRlIF9jYWNoZWRJc1Jlc291cmNlOiBib29sZWFuID0gZmFsc2VcclxuICBwcml2YXRlIF9jYWNoZWRJc01pbGVzdG9uZTogYm9vbGVhbiA9IGZhbHNlXHJcbiAgcHJpdmF0ZSBfY2FjaGVkSXNNaWxlc3RvbmVMb2NrZWQ6IGJvb2xlYW4gPSBmYWxzZVxyXG4gIHByaXZhdGUgX2NhY2hlZElzUGFyZW50TWlsZXN0b25lTG9ja2VkOiBib29sZWFuID0gZmFsc2VcclxuICBwcml2YXRlIF9jYWNoZWRJc0NvbnRlbnRVbmxvY2tlZDogYm9vbGVhbiA9IHRydWVcclxuICBwcml2YXRlIF9jYWNoZWRDaGVja0ZvckN1cmF0ZWRQcm9ncmFtOiBib29sZWFuID0gZmFsc2VcclxuICBwcml2YXRlIF9jYWNoZWRJc01pbGVzdG9uZUFzc2Vzc21lbnQ6IGJvb2xlYW4gPSBmYWxzZVxyXG4gIHByaXZhdGUgX2NhY2hlZElzTWlsZXN0b25lQXNzZXNzbWVudExvY2tlZDogYm9vbGVhbiA9IGZhbHNlXHJcbiAgcHJpdmF0ZSBfY2FjaGVkUmVzb3VyY2VMaW5rOiB7IHVybDogc3RyaW5nOyBxdWVyeVBhcmFtczogeyBba2V5OiBzdHJpbmddOiBhbnkgfSB9ID0geyB1cmw6ICcnLCBxdWVyeVBhcmFtczoge30gfVxyXG4gIHByaXZhdGUgX2NhY2hlSW5pdGlhbGl6ZWQ6IGJvb2xlYW4gPSBmYWxzZVxyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgZXZlbnRzOiBFdmVudFNlcnZpY2UsXHJcbiAgICBwcml2YXRlIGRpYWxvZzogTWF0RGlhbG9nLFxyXG4gICAgcHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyLFxyXG4gICAgcHJpdmF0ZSBjZXJ0aWZpY2F0ZVNlcnZpY2U6IENlcnRpZmljYXRlU2VydmljZSxcclxuICAgIHByaXZhdGUgYXBwVG9jU3ZjOiBBcHBUb2NTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBjb250ZW50TGFuZ1N2YzogQ29udGVudExhbmd1YWdlU2VydmljZSxcclxuICAgIHByaXZhdGUgcmVzb3VyY2VEb3dubG9hZEhlbHBlclN2YzogUmVzb3VyY2VEb3dubG9hZEhlbHBlclNlcnZpY2UsICAgIFxyXG4gICAgcHJpdmF0ZSBjb25maWdTdmM6IENvbmZpZ3VyYXRpb25zU2VydmljZSxcclxuICAgIHByaXZhdGUgc25hY2tCYXI6IE1hdFNuYWNrQmFyXHJcbiAgKSB7IH1cclxuXHJcbiAgbmdPbkluaXQoKSB7XHJcbiAgICB0aGlzLmV2YWx1YXRlSW1tZWRpYXRlQ2hpbGRyZW5TdHJ1Y3R1cmUoKVxyXG4gICAgdGhpcy5pbml0aWFsaXplQ29tcHV0ZWRQcm9wZXJ0aWVzKClcclxuICAgIC8vIHRoaXMucm91dGUuZGF0YS5zdWJzY3JpYmUoZGF0YSA9PiB7XHJcbiAgICAvLyAgICAgdGhpcy5kZWZhdWx0VGh1bWJuYWlsID0gZGF0YS5jb25maWdEYXRhLmRhdGEubG9nb3MuZGVmYXVsdENvbnRlbnRcclxuICAgIC8vICAgfVxyXG4gICAgLy8gKVxyXG4gICAgdGhpcy5yZXNvdXJjZVNjcm9sbCgpXHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBJbml0aWFsaXplIGFsbCBjb21wdXRlZCBwcm9wZXJ0aWVzIG9uY2UgdG8gYXZvaWQgZXhwZW5zaXZlIGdldHRlciBjYWxjdWxhdGlvbnNcclxuICAgKiBvbiBldmVyeSBjaGFuZ2UgZGV0ZWN0aW9uIGN5Y2xlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBpbml0aWFsaXplQ29tcHV0ZWRQcm9wZXJ0aWVzKCkge1xyXG4gICAgdGhpcy5jb21wdXRlQWxsQ2FjaGVkUHJvcGVydGllcygpXHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDb21wdXRlIGFsbCBjYWNoZWQgcHJvcGVydGllcyBhdCBvbmNlIGZvciBwZXJmb3JtYW5jZSBvcHRpbWl6YXRpb25cclxuICAgKi9cclxuICBwcml2YXRlIGNvbXB1dGVBbGxDYWNoZWRQcm9wZXJ0aWVzKCkge1xyXG4gICAgaWYgKCF0aGlzLmNvbnRlbnQpIHtcclxuICAgICAgdGhpcy5fY2FjaGVJbml0aWFsaXplZCA9IGZhbHNlXHJcbiAgICAgIHJldHVyblxyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGNvbnRlbnRJZCA9IHRoaXMuY29udGVudC5pZGVudGlmaWVyXHJcbiAgICBjb25zdCBoYXNoRGF0YSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YSAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbY29udGVudElkXVxyXG5cclxuICAgIC8vIFVzZSBoYXNobWFwIGRhdGEgaWYgYXZhaWxhYmxlIGZvciBwcmUtY29tcHV0ZWQgdmFsdWVzXHJcbiAgICBpZiAoaGFzaERhdGEpIHtcclxuICAgICAgdGhpcy5fY2FjaGVkSXNDb2xsZWN0aW9uID0gaGFzaERhdGEuaXNDb2xsZWN0aW9uICE9PSB1bmRlZmluZWQgPyBcclxuICAgICAgICBoYXNoRGF0YS5pc0NvbGxlY3Rpb24gOiB0aGlzLmNvbnRlbnQubWltZVR5cGUgPT09IE5zQ29udGVudC5FTWltZVR5cGVzLkNPTExFQ1RJT05cclxuICAgICAgdGhpcy5fY2FjaGVkSXNNb2R1bGUgPSBoYXNoRGF0YS5pc01vZHVsZSAhPT0gdW5kZWZpbmVkID8gXHJcbiAgICAgICAgaGFzaERhdGEuaXNNb2R1bGUgOiB0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5NT0RVTEVcclxuICAgICAgdGhpcy5fY2FjaGVkSXNSZXNvdXJjZSA9IGhhc2hEYXRhLmlzUmVzb3VyY2UgIT09IHVuZGVmaW5lZCA/IFxyXG4gICAgICAgIGhhc2hEYXRhLmlzUmVzb3VyY2UgOiB0aGlzLmNvbXB1dGVJc1Jlc291cmNlKClcclxuICAgICAgdGhpcy5fY2FjaGVkSXNNaWxlc3RvbmUgPSBoYXNoRGF0YS5pc01pbGVzdG9uZSAhPT0gdW5kZWZpbmVkID8gXHJcbiAgICAgICAgaGFzaERhdGEuaXNNaWxlc3RvbmUgOiB0aGlzLmNvbXB1dGVJc01pbGVzdG9uZSgpXHJcbiAgICAgIHRoaXMuX2NhY2hlZElzTWlsZXN0b25lTG9ja2VkID0gaGFzaERhdGEuY29tcHV0ZWRJc0xvY2tlZCAhPT0gdW5kZWZpbmVkID8gXHJcbiAgICAgICAgaGFzaERhdGEuY29tcHV0ZWRJc0xvY2tlZCA6IHRoaXMuY29tcHV0ZUlzTWlsZXN0b25lTG9ja2VkKClcclxuICAgICAgdGhpcy5fY2FjaGVkSXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQgPSBoYXNoRGF0YS5pc1BhcmVudE1pbGVzdG9uZUxvY2tlZCAhPT0gdW5kZWZpbmVkID8gXHJcbiAgICAgICAgaGFzaERhdGEuaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQgOiB0aGlzLmNvbXB1dGVJc1BhcmVudE1pbGVzdG9uZUxvY2tlZCgpXHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAvLyBGYWxsYmFjayB0byBkaXJlY3QgY29tcHV0YXRpb24gaWYgaGFzaG1hcCBub3QgYXZhaWxhYmxlXHJcbiAgICAgIHRoaXMuX2NhY2hlZElzQ29sbGVjdGlvbiA9IHRoaXMuY29udGVudC5taW1lVHlwZSA9PT0gTnNDb250ZW50LkVNaW1lVHlwZXMuQ09MTEVDVElPTlxyXG4gICAgICB0aGlzLl9jYWNoZWRJc01vZHVsZSA9IHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk1PRFVMRVxyXG4gICAgICB0aGlzLl9jYWNoZWRJc1Jlc291cmNlID0gdGhpcy5jb21wdXRlSXNSZXNvdXJjZSgpXHJcbiAgICAgIHRoaXMuX2NhY2hlZElzTWlsZXN0b25lID0gdGhpcy5jb21wdXRlSXNNaWxlc3RvbmUoKVxyXG4gICAgICB0aGlzLl9jYWNoZWRJc01pbGVzdG9uZUxvY2tlZCA9IHRoaXMuY29tcHV0ZUlzTWlsZXN0b25lTG9ja2VkKClcclxuICAgICAgdGhpcy5fY2FjaGVkSXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQgPSB0aGlzLmNvbXB1dGVJc1BhcmVudE1pbGVzdG9uZUxvY2tlZCgpXHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5fY2FjaGVkQ2hlY2tGb3JDdXJhdGVkUHJvZ3JhbSA9IHRoaXMuY29tcHV0ZUNoZWNrRm9yQ3VyYXRlZFByb2dyYW0oKVxyXG4gICAgdGhpcy5fY2FjaGVkSXNDb250ZW50VW5sb2NrZWQgPSB0aGlzLmNvbXB1dGVJc0NvbnRlbnRVbmxvY2tlZCgpXHJcbiAgICB0aGlzLl9jYWNoZWRJc01pbGVzdG9uZUFzc2Vzc21lbnQgPSB0aGlzLmNvbXB1dGVJc01pbGVzdG9uZUFzc2Vzc21lbnQoKVxyXG4gICAgdGhpcy5fY2FjaGVkSXNNaWxlc3RvbmVBc3Nlc3NtZW50TG9ja2VkID0gdGhpcy5jb21wdXRlSXNNaWxlc3RvbmVBc3Nlc3NtZW50TG9ja2VkKClcclxuICAgIHRoaXMuX2NhY2hlZFJlc291cmNlTGluayA9IHRoaXMuY29tcHV0ZVJlc291cmNlTGluaygpXHJcbiAgICB0aGlzLl9jYWNoZUluaXRpYWxpemVkID0gdHJ1ZVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjb21wdXRlSXNSZXNvdXJjZSgpOiBib29sZWFuIHtcclxuICAgIGlmICghdGhpcy5jb250ZW50KSByZXR1cm4gZmFsc2VcclxuICAgIHJldHVybiAoXHJcbiAgICAgIHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LlJFU09VUkNFIHx8XHJcbiAgICAgIHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFIHx8XHJcbiAgICAgIHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgfHxcclxuICAgICAgdGhpcy5jb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuQ09NUF9BU1NFU1NNRU5UXHJcbiAgICApXHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGNvbXB1dGVJc01pbGVzdG9uZSgpOiBib29sZWFuIHtcclxuICAgIGlmICghdGhpcy5jb250ZW50KSByZXR1cm4gZmFsc2VcclxuICAgIGNvbnN0IHByaW1hcnlDYXQgPSB0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5IGFzIHN0cmluZ1xyXG4gICAgY29uc3QgY291cnNlQ2F0ID0gdGhpcy5jb250ZW50LmNvdXJzZUNhdGVnb3J5IGFzIHN0cmluZ1xyXG4gICAgcmV0dXJuIHByaW1hcnlDYXQgPT09ICdNaWxlc3RvbmUnIHx8IGNvdXJzZUNhdCA9PT0gJ01pbGVzdG9uZSdcclxuICB9XHJcblxyXG4gIHByaXZhdGUgY29tcHV0ZUNoZWNrRm9yQ3VyYXRlZFByb2dyYW0oKTogYm9vbGVhbiB7XHJcbiAgICBpZiAodGhpcy5jb250ZW50ICYmIHRoaXMuY29udGVudC5wYXJlbnQgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhICYmIHRoaXMuaGllcmFyY2h5TWFwRGF0YVt0aGlzLmNvbnRlbnQucGFyZW50XSkge1xyXG4gICAgICBjb25zdCBwYXJlbnREYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3RoaXMuY29udGVudC5wYXJlbnRdXHJcbiAgICAgIHJldHVybiBwYXJlbnREYXRhICYmIHBhcmVudERhdGEucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5DVVJBVEVEX1BST0dSQU0gJiZcclxuICAgICAgICBwYXJlbnREYXRhLmNvbXBhdGliaWxpdHlMZXZlbCA+PSA1ICYmXHJcbiAgICAgICAgcGFyZW50RGF0YS5jb250ZXh0TG9ja2luZ1R5cGUgPT09IE5zQ29udGVudC5FQ29udGV4dExvY2tpbmdUeXBlLkNPVVJTRV9BU1NFU1NNRU5UX09OTFlcclxuICAgIH1cclxuICAgIHJldHVybiBmYWxzZVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjb21wdXRlSXNDb250ZW50VW5sb2NrZWQoKTogYm9vbGVhbiB7XHJcbiAgICBpZiAodGhpcy5fY2FjaGVkQ2hlY2tGb3JDdXJhdGVkUHJvZ3JhbSkge1xyXG4gICAgICBpZiAodGhpcy5jb250ZW50ICYmIHRoaXMuY29udGVudC5wYXJlbnQgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhICYmIHRoaXMuaGllcmFyY2h5TWFwRGF0YVt0aGlzLmNvbnRlbnQucGFyZW50XSkge1xyXG4gICAgICAgIGNvbnN0IHBhcmVudERhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbdGhpcy5jb250ZW50LnBhcmVudF1cclxuICAgICAgICBsZXQgY29tcGxldGVkTGVhZk5vZGVzOiBhbnlbXSA9IFtdXHJcbiAgICAgICAgcGFyZW50RGF0YS5sZWFmTm9kZXMuZm9yRWFjaCgoX2VsZTogYW55KSA9PiB7XHJcbiAgICAgICAgICBpZiAodGhpcy5oaWVyYXJjaHlNYXBEYXRhICYmIHRoaXMuaGllcmFyY2h5TWFwRGF0YVtfZWxlXSkge1xyXG4gICAgICAgICAgICBjb25zdCBjaGlsZERhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbX2VsZV1cclxuICAgICAgICAgICAgaWYgKGNoaWxkRGF0YSAmJiBjaGlsZERhdGEuY29tcGxldGlvblN0YXR1cyA9PT0gMikge1xyXG4gICAgICAgICAgICAgIGNvbXBsZXRlZExlYWZOb2Rlcy5wdXNoKGNoaWxkRGF0YSlcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pXHJcbiAgICAgICAgcmV0dXJuIGNvbXBsZXRlZExlYWZOb2Rlcy5sZW5ndGggPj0gcGFyZW50RGF0YS5sZWFmTm9kZXNDb3VudCAtIDFcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuICAgIHJldHVybiB0cnVlXHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGNvbXB1dGVSZXNvdXJjZUxpbmsoKTogeyB1cmw6IHN0cmluZzsgcXVlcnlQYXJhbXM6IHsgW2tleTogc3RyaW5nXTogYW55IH0gfSB7XHJcbiAgICBpZiAodGhpcy5jb250ZW50KSB7XHJcbiAgICAgIGxldCBtaW1lVHlwZTogYW55ID0gJydcclxuICAgICAgaWYgKHRoaXMuY29udGVudCAmJiB0aGlzLmNvbnRlbnQuY291cnNlQ2F0ZWdvcnkgPT09ICdQcmUgRW5yb2xtZW50IEFzc2Vzc21lbnQnICYmXHJcbiAgICAgICAgdGhpcy5jb250ZW50Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLmVrc3RlcC5jb250ZW50LWNvbGxlY3Rpb24nXHJcbiAgICAgICkge1xyXG4gICAgICAgIG1pbWVUeXBlID0gJ2FwcGxpY2F0aW9uL3ZuZC5zdW5iaXJkLnF1ZXN0aW9uc2V0J1xyXG4gICAgICAgIHRoaXMuY29udGVudC5taW1lVHlwZSA9IE5zQ29udGVudC5FTWltZVR5cGVzLkZJTkFMX0FTU0VTU01FTlRcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBtaW1lVHlwZSA9IHRoaXMuY29udGVudC5taW1lVHlwZVxyXG4gICAgICB9XHJcbiAgICAgIGNvbnN0IHNlbGVjdGVkTGFuZ3VhZ2UgPSB0aGlzLm1sQ291cnNlID8gdGhpcy5jb250ZW50TGFuZ1N2Yy5nZXRTZWxlY3RlZExhbmd1YWdlKHRoaXMubWxDb3Vyc2UpIDogdW5kZWZpbmVkXHJcbiAgICAgIHJldHVybiB2aWV3ZXJSb3V0ZUdlbmVyYXRvcihcclxuICAgICAgICB0aGlzLmNvbnRlbnQuaWRlbnRpZmllcixcclxuICAgICAgICBtaW1lVHlwZSxcclxuICAgICAgICB0aGlzLmJhc2VDb250ZW50UmVhZERhdGE/LmlkZW50aWZpZXIgfHwgdGhpcy5yb290SWQsXHJcbiAgICAgICAgdGhpcy5iYXNlQ29udGVudFJlYWREYXRhPy5jb250ZW50VHlwZSB8fCB0aGlzLnJvb3RDb250ZW50VHlwZSxcclxuICAgICAgICB0aGlzLmZvclByZXZpZXcsXHJcbiAgICAgICAgdGhpcy5jb250ZW50LnByaW1hcnlDYXRlZ29yeSxcclxuICAgICAgICB0aGlzLmJhdGNoSWQsXHJcbiAgICAgICAgdGhpcy5jb250ZW50Py5uYW1lIHx8IHRoaXMuYmFzZUNvbnRlbnRSZWFkRGF0YT8ubmFtZSxcclxuICAgICAgICAoc2VsZWN0ZWRMYW5ndWFnZSA/IHNlbGVjdGVkTGFuZ3VhZ2UubGFuZ0lkIDogbnVsbCksXHJcbiAgICAgICAgKHNlbGVjdGVkTGFuZ3VhZ2UgPyBzZWxlY3RlZExhbmd1YWdlLmlkZW50aWZpZXIgOiBudWxsKSxcclxuICAgICAgKVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHsgdXJsOiAnJywgcXVlcnlQYXJhbXM6IHt9IH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgY29tcHV0ZUlzTWlsZXN0b25lTG9ja2VkKCk6IGJvb2xlYW4ge1xyXG4gICAgLy8gT25seSBhcHBseSBtaWxlc3RvbmUgbG9ja2luZyBmb3IgTGVhcm5pbmcgUGF0aHdheSBjb250ZW50XHJcbiAgICBpZiAoIXRoaXMuYmFzZUNvbnRlbnRSZWFkRGF0YSB8fCB0aGlzLmJhc2VDb250ZW50UmVhZERhdGEuY291cnNlQ2F0ZWdvcnkgIT09ICdMZWFybmluZyBQYXRod2F5Jykge1xyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIXRoaXMuY29udGVudCkge1xyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuXHJcbiAgICAvLyBDaGVjayBpZiBjdXJyZW50IGNvbnRlbnQgaXMgYSBNaWxlc3RvbmVcclxuICAgIGlmICghdGhpcy5fY2FjaGVkSXNNaWxlc3RvbmUgJiYgIXRoaXMuY29tcHV0ZUlzTWlsZXN0b25lKCkpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlXHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ2hlY2sgaWYgaGFzaG1hcCBoYXMgcHJlLWNvbXB1dGVkIGxvY2tpbmcgc3RhdHVzIChwcmVmZXJyZWQgLSBjb21wdXRlZCBieSBzZXJ2aWNlKVxyXG4gICAgY29uc3QgaGFzaERhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGEgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3RoaXMuY29udGVudC5pZGVudGlmaWVyXVxyXG4gICAgY29uc29sZS5sb2coYGNvbXB1dGVJc01pbGVzdG9uZUxvY2tlZCBmb3IgJHt0aGlzLmNvbnRlbnQuaWRlbnRpZmllcn0gKCR7dGhpcy5jb250ZW50Lm5hbWV9KTpgLCB7XHJcbiAgICAgIGhhc2hEYXRhLFxyXG4gICAgICBjb21wdXRlZElzTG9ja2VkOiBoYXNoRGF0YT8uY29tcHV0ZWRJc0xvY2tlZCxcclxuICAgICAgY29udGVudElzTG9ja2VkOiB0aGlzLmNvbnRlbnQuaXNMb2NrZWRcclxuICAgIH0pXHJcbiAgICBcclxuICAgIGlmIChoYXNoRGF0YSAmJiBoYXNoRGF0YS5jb21wdXRlZElzTG9ja2VkICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgcmV0dXJuIGhhc2hEYXRhLmNvbXB1dGVkSXNMb2NrZWRcclxuICAgIH1cclxuXHJcbiAgICAvLyBJZiBtaWxlc3RvbmUgaGFzIGlzTG9ja2VkIGZsYWcgZXhwbGljaXRseSBzZXQgdG8gZmFsc2UsIGl0J3MgdW5sb2NrZWRcclxuICAgIGlmICh0aGlzLmNvbnRlbnQuaXNMb2NrZWQgPT09IGZhbHNlKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZVxyXG4gICAgfVxyXG5cclxuICAgIC8vIEZhbGxiYWNrOiBBbGwgbWlsZXN0b25lcyBhcmUgbG9ja2VkIGJ5IGRlZmF1bHQgdW50aWwgY29tcHV0ZWQgb3RoZXJ3aXNlXHJcbiAgICAvLyBUaGlzIGVuc3VyZXMgcHJvcGVyIGxvY2tpbmcgdW50aWwgdGhlIGhhc2htYXAgaXMgdXBkYXRlZCB3aXRoIHByb2dyZXNzXHJcbiAgICByZXR1cm4gdHJ1ZVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjb21wdXRlSXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQoKTogYm9vbGVhbiB7XHJcbiAgICBpZiAodGhpcy5wYXJlbnRNaWxlc3RvbmVMb2NrZWQpIHtcclxuICAgICAgcmV0dXJuIHRydWVcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIXRoaXMuYmFzZUNvbnRlbnRSZWFkRGF0YSB8fCB0aGlzLmJhc2VDb250ZW50UmVhZERhdGEuY291cnNlQ2F0ZWdvcnkgIT09ICdMZWFybmluZyBQYXRod2F5Jykge1xyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIXRoaXMuY29udGVudCB8fCAhdGhpcy5oaWVyYXJjaHlNYXBEYXRhKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZVxyXG4gICAgfVxyXG5cclxuICAgIC8vIENoZWNrIGhhc2htYXAgZm9yIHByZS1jb21wdXRlZCB2YWx1ZVxyXG4gICAgY29uc3QgaGFzaERhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbdGhpcy5jb250ZW50LmlkZW50aWZpZXJdXHJcbiAgICBpZiAoaGFzaERhdGEgJiYgaGFzaERhdGEuaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICByZXR1cm4gaGFzaERhdGEuaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWRcclxuICAgIH1cclxuXHJcbiAgICAvLyBUcmF2ZXJzZSB1cCB0aGUgaGllcmFyY2h5IHRvIGZpbmQgaWYgYW55IGFuY2VzdG9yIGlzIGEgbG9ja2VkIE1pbGVzdG9uZVxyXG4gICAgbGV0IGN1cnJlbnRQYXJlbnRJZCA9IHRoaXMuY29udGVudC5wYXJlbnRcclxuICAgIGNvbnN0IG1heERlcHRoID0gNVxyXG4gICAgbGV0IGRlcHRoID0gMFxyXG5cclxuICAgIHdoaWxlIChjdXJyZW50UGFyZW50SWQgJiYgZGVwdGggPCBtYXhEZXB0aCkge1xyXG4gICAgICBjb25zdCBwYXJlbnREYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2N1cnJlbnRQYXJlbnRJZF1cclxuICAgICAgaWYgKHBhcmVudERhdGEpIHtcclxuICAgICAgICBpZiAoKHBhcmVudERhdGEuaXNNaWxlc3RvbmUgfHwgcGFyZW50RGF0YS5wcmltYXJ5Q2F0ZWdvcnkgPT09ICdNaWxlc3RvbmUnIHx8IHBhcmVudERhdGEuY291cnNlQ2F0ZWdvcnkgPT09ICdNaWxlc3RvbmUnKSAmJiBcclxuICAgICAgICAgICAgKHBhcmVudERhdGEuY29tcHV0ZWRJc0xvY2tlZCB8fCBwYXJlbnREYXRhLmlzTG9ja2VkKSkge1xyXG4gICAgICAgICAgcmV0dXJuIHRydWVcclxuICAgICAgICB9XHJcbiAgICAgICAgY3VycmVudFBhcmVudElkID0gcGFyZW50RGF0YS5wYXJlbnRcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBicmVha1xyXG4gICAgICB9XHJcbiAgICAgIGRlcHRoKytcclxuICAgIH1cclxuICAgIHJldHVybiBmYWxzZVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2hlY2sgaWYgY3VycmVudCBjb250ZW50IGlzIGEgbWlsZXN0b25lIGFzc2Vzc21lbnQgKENvdXJzZSBBc3Nlc3NtZW50IG9yIEZpbmFsIEFzc2Vzc21lbnQgaW5zaWRlIGEgTWlsZXN0b25lKVxyXG4gICAqL1xyXG4gIHByaXZhdGUgY29tcHV0ZUlzTWlsZXN0b25lQXNzZXNzbWVudCgpOiBib29sZWFuIHtcclxuICAgIGlmICghdGhpcy5iYXNlQ29udGVudFJlYWREYXRhIHx8IHRoaXMuYmFzZUNvbnRlbnRSZWFkRGF0YS5jb3Vyc2VDYXRlZ29yeSAhPT0gJ0xlYXJuaW5nIFBhdGh3YXknKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZVxyXG4gICAgfVxyXG5cclxuICAgIGlmICghdGhpcy5jb250ZW50IHx8ICF0aGlzLmhpZXJhcmNoeU1hcERhdGEpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlXHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBhbiBhc3Nlc3NtZW50XHJcbiAgICBjb25zdCBpc0Fzc2Vzc21lbnQgPSBcclxuICAgICAgdGhpcy5jb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gJ0NvdXJzZSBBc3Nlc3NtZW50JyB8fFxyXG4gICAgICB0aGlzLmNvbnRlbnQuY291cnNlQ2F0ZWdvcnkgPT09ICdDb3Vyc2UgQXNzZXNzbWVudCcgfHxcclxuICAgICAgKHRoaXMuY29udGVudC5uYW1lICYmIHRoaXMuY29udGVudC5uYW1lLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoJ2Fzc2Vzc21lbnQnKSlcclxuXHJcbiAgICBpZiAoIWlzQXNzZXNzbWVudCkge1xyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuXHJcbiAgICAvLyBDaGVjayBpZiB0aGUgcGFyZW50IG9yIGdyYW5kcGFyZW50IGlzIGEgbWlsZXN0b25lIChzaW5jZSBhc3Nlc3NtZW50cyBjYW4gYmUgaW5zaWRlIGNvdXJzZXMgaW5zaWRlIG1pbGVzdG9uZXMpXHJcbiAgICBpZiAodGhpcy5jb250ZW50LnBhcmVudCAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbdGhpcy5jb250ZW50LnBhcmVudF0pIHtcclxuICAgICAgY29uc3QgcGFyZW50RGF0YSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YVt0aGlzLmNvbnRlbnQucGFyZW50XVxyXG4gICAgICBcclxuICAgICAgLy8gQ2hlY2sgaWYgZGlyZWN0IHBhcmVudCBpcyBhIG1pbGVzdG9uZVxyXG4gICAgICBpZiAocGFyZW50RGF0YS5pc01pbGVzdG9uZSB8fCBwYXJlbnREYXRhLnByaW1hcnlDYXRlZ29yeSA9PT0gJ01pbGVzdG9uZScgfHwgcGFyZW50RGF0YS5jb3Vyc2VDYXRlZ29yeSA9PT0gJ01pbGVzdG9uZScpIHtcclxuICAgICAgICByZXR1cm4gdHJ1ZVxyXG4gICAgICB9XHJcbiAgICAgIFxyXG4gICAgICAvLyBDaGVjayBpZiBncmFuZHBhcmVudCBpcyBhIG1pbGVzdG9uZSAoZm9yIGFzc2Vzc21lbnRzIGluc2lkZSBjb3Vyc2VzIGluc2lkZSBtaWxlc3RvbmVzKVxyXG4gICAgICBpZiAocGFyZW50RGF0YS5wYXJlbnQgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3BhcmVudERhdGEucGFyZW50XSkge1xyXG4gICAgICAgIGNvbnN0IGdyYW5kcGFyZW50RGF0YSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YVtwYXJlbnREYXRhLnBhcmVudF1cclxuICAgICAgICByZXR1cm4gZ3JhbmRwYXJlbnREYXRhLmlzTWlsZXN0b25lIHx8IGdyYW5kcGFyZW50RGF0YS5wcmltYXJ5Q2F0ZWdvcnkgPT09ICdNaWxlc3RvbmUnIHx8IGdyYW5kcGFyZW50RGF0YS5jb3Vyc2VDYXRlZ29yeSA9PT0gJ01pbGVzdG9uZSdcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBmYWxzZVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2hlY2sgaWYgbWlsZXN0b25lIGFzc2Vzc21lbnQgc2hvdWxkIGJlIGxvY2tlZFxyXG4gICAqIEFzc2Vzc21lbnQgaXMgbG9ja2VkIGlmOlxyXG4gICAqIDEuIEl0J3MgYW4gYXNzZXNzbWVudCB3aXRoaW4gYSBtaWxlc3RvbmVcclxuICAgKiAyLiBUaGUgcGFyZW50IG1pbGVzdG9uZSBpcyB1bmxvY2tlZCAob3RoZXJ3aXNlIGhhbmRsZWQgYnkgcGFyZW50IG1pbGVzdG9uZSBsb2NrKVxyXG4gICAqIDMuIE5PVCBhbGwgbWFuZGF0b3J5IGNvbnRlbnQgaW4gdGhlIHNhbWUgbWlsZXN0b25lIGlzIGNvbXBsZXRlZFxyXG4gICAqL1xyXG4gIHByaXZhdGUgY29tcHV0ZUlzTWlsZXN0b25lQXNzZXNzbWVudExvY2tlZCgpOiBib29sZWFuIHtcclxuICAgIC8vIE9ubHkgYXBwbHkgdG8gYXNzZXNzbWVudHMgd2l0aGluIG1pbGVzdG9uZXNcclxuICAgIGlmICghdGhpcy5fY2FjaGVkSXNNaWxlc3RvbmVBc3Nlc3NtZW50ICYmICF0aGlzLmNvbXB1dGVJc01pbGVzdG9uZUFzc2Vzc21lbnQoKSkge1xyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuXHJcbiAgICAvLyBDaGVjayBpZiBoYXNobWFwIGhhcyBwcmUtY29tcHV0ZWQgYXNzZXNzbWVudCBsb2NraW5nIHN0YXR1c1xyXG4gICAgY29uc3QgaGFzaERhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGEgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3RoaXMuY29udGVudD8uaWRlbnRpZmllciB8fCAnJ11cclxuICAgIGlmIChoYXNoRGF0YSAmJiBoYXNoRGF0YS5pc0Fzc2Vzc21lbnRMb2NrZWQgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICByZXR1cm4gaGFzaERhdGEuaXNBc3Nlc3NtZW50TG9ja2VkXHJcbiAgICB9XHJcblxyXG4gICAgLy8gSWYgYWxyZWFkeSBjb21wbGV0ZWQsIGRvbid0IGxvY2tcclxuICAgIGlmICh0aGlzLmNvbnRlbnQgJiYgKHRoaXMuY29udGVudC5jb21wbGV0aW9uU3RhdHVzID09PSAyIHx8IFxyXG4gICAgICAgICh0aGlzLmNvbnRlbnQuY29tcGxldGlvblBlcmNlbnRhZ2UgJiYgdGhpcy5jb250ZW50LmNvbXBsZXRpb25QZXJjZW50YWdlID49IDEwMCkpKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZVxyXG4gICAgfVxyXG5cclxuICAgIC8vIEZpbmQgdGhlIG1pbGVzdG9uZSBJRCAoY291bGQgYmUgcGFyZW50IG9yIGdyYW5kcGFyZW50KVxyXG4gICAgbGV0IG1pbGVzdG9uZUlkOiBzdHJpbmcgfCB1bmRlZmluZWRcclxuICAgIGxldCBtaWxlc3RvbmU6IGFueVxyXG5cclxuICAgIC8vIENoZWNrIGlmIGRpcmVjdCBwYXJlbnQgaXMgbWlsZXN0b25lXHJcbiAgICBpZiAodGhpcy5jb250ZW50Py5wYXJlbnQgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhICYmIHRoaXMuaGllcmFyY2h5TWFwRGF0YVt0aGlzLmNvbnRlbnQucGFyZW50XSkge1xyXG4gICAgICBjb25zdCBwYXJlbnREYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3RoaXMuY29udGVudC5wYXJlbnRdXHJcbiAgICAgIGlmIChwYXJlbnREYXRhLmlzTWlsZXN0b25lIHx8IHBhcmVudERhdGEucHJpbWFyeUNhdGVnb3J5ID09PSAnTWlsZXN0b25lJyB8fCBwYXJlbnREYXRhLmNvdXJzZUNhdGVnb3J5ID09PSAnTWlsZXN0b25lJykge1xyXG4gICAgICAgIG1pbGVzdG9uZUlkID0gdGhpcy5jb250ZW50LnBhcmVudFxyXG4gICAgICAgIG1pbGVzdG9uZSA9IHBhcmVudERhdGFcclxuICAgICAgfSBlbHNlIGlmIChwYXJlbnREYXRhLnBhcmVudCAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbcGFyZW50RGF0YS5wYXJlbnRdKSB7XHJcbiAgICAgICAgLy8gQ2hlY2sgaWYgZ3JhbmRwYXJlbnQgaXMgbWlsZXN0b25lXHJcbiAgICAgICAgY29uc3QgZ3JhbmRwYXJlbnREYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3BhcmVudERhdGEucGFyZW50XVxyXG4gICAgICAgIGlmIChncmFuZHBhcmVudERhdGEuaXNNaWxlc3RvbmUgfHwgZ3JhbmRwYXJlbnREYXRhLnByaW1hcnlDYXRlZ29yeSA9PT0gJ01pbGVzdG9uZScgfHwgZ3JhbmRwYXJlbnREYXRhLmNvdXJzZUNhdGVnb3J5ID09PSAnTWlsZXN0b25lJykge1xyXG4gICAgICAgICAgbWlsZXN0b25lSWQgPSBwYXJlbnREYXRhLnBhcmVudFxyXG4gICAgICAgICAgbWlsZXN0b25lID0gZ3JhbmRwYXJlbnREYXRhXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCFtaWxlc3RvbmVJZCB8fCAhbWlsZXN0b25lKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZVxyXG4gICAgfVxyXG4gICAgXHJcbiAgICAvLyBJZiB0aGUgcGFyZW50IG1pbGVzdG9uZSBpdHNlbGYgaXMgbG9ja2VkLCBkb24ndCBhZGQgYWRkaXRpb25hbCBsb2NraW5nXHJcbiAgICAvLyAodGhlIHBhcmVudCBsb2NrIHdpbGwgaGFuZGxlIGl0KVxyXG4gICAgaWYgKG1pbGVzdG9uZS5jb21wdXRlZElzTG9ja2VkIHx8IG1pbGVzdG9uZS5pc0xvY2tlZCkge1xyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuXHJcbiAgICAvLyBDaGVjayBpZiBhbGwgbWFuZGF0b3J5IGNvbnRlbnQgaW4gdGhlIG1pbGVzdG9uZSBpcyBjb21wbGV0ZWRcclxuICAgIGxldCBtYW5kYXRvcnlDb3VudCA9IDBcclxuICAgIGxldCBjb21wbGV0ZWRNYW5kYXRvcnlDb3VudCA9IDBcclxuXHJcbiAgICAvLyBDaGVjayBhbGwgaXRlbXMgaW4gaGFzaG1hcCB0aGF0IGJlbG9uZyB0byB0aGlzIG1pbGVzdG9uZVxyXG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXModGhpcy5oaWVyYXJjaHlNYXBEYXRhKSkge1xyXG4gICAgICBjb25zdCBpdGVtID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2tleV1cclxuXHJcbiAgICAgIC8vIENoZWNrIGlmIHRoaXMgaXRlbSBiZWxvbmdzIHRvIHRoZSBtaWxlc3RvbmUgKGRpcmVjdCBjaGlsZCBvciBuZXN0ZWQpXHJcbiAgICAgIC8vIE1vc3QgY29udGVudCB3aWxsIGJlIHVuZGVyIGNvdXJzZXMgdGhhdCBhcmUgdW5kZXIgbWlsZXN0b25lXHJcbiAgICAgIGxldCBpdGVtQmVsb25nc1RvTWlsZXN0b25lID0gZmFsc2VcclxuICAgICAgaWYgKGl0ZW0ucGFyZW50ID09PSBtaWxlc3RvbmVJZCkge1xyXG4gICAgICAgIGl0ZW1CZWxvbmdzVG9NaWxlc3RvbmUgPSB0cnVlXHJcbiAgICAgIH0gZWxzZSBpZiAoaXRlbS5wYXJlbnQgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2l0ZW0ucGFyZW50XSkge1xyXG4gICAgICAgIC8vIENoZWNrIGlmIHBhcmVudCBpcyBhIGNvdXJzZSB1bmRlciB0aGlzIG1pbGVzdG9uZVxyXG4gICAgICAgIGNvbnN0IHBhcmVudEl0ZW0gPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbaXRlbS5wYXJlbnRdXHJcbiAgICAgICAgaWYgKHBhcmVudEl0ZW0ucGFyZW50ID09PSBtaWxlc3RvbmVJZCAmJiBwYXJlbnRJdGVtLnByaW1hcnlDYXRlZ29yeSA9PT0gJ0NvdXJzZScpIHtcclxuICAgICAgICAgIGl0ZW1CZWxvbmdzVG9NaWxlc3RvbmUgPSB0cnVlXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoIWl0ZW1CZWxvbmdzVG9NaWxlc3RvbmUpIGNvbnRpbnVlXHJcblxyXG4gICAgICAvLyBTa2lwIGFzc2Vzc21lbnRzIC0gd2UncmUgY2hlY2tpbmcgaWYgbGVhcm5pbmcgY29udGVudCBpcyBjb21wbGV0ZVxyXG4gICAgICBjb25zdCBpc0l0ZW1Bc3Nlc3NtZW50ID1cclxuICAgICAgICBpdGVtLnByaW1hcnlDYXRlZ29yeSA9PT0gJ0NvdXJzZSBBc3Nlc3NtZW50JyB8fFxyXG4gICAgICAgIGl0ZW0ucHJpbWFyeUNhdGVnb3J5ID09PSAnRmluYWwgQXNzZXNzbWVudCcgfHxcclxuICAgICAgICBpdGVtLnByaW1hcnlDYXRlZ29yeSA9PT0gJ1N0YW5kYWxvbmUgQXNzZXNzbWVudCcgfHxcclxuICAgICAgICBpdGVtLmNvdXJzZUNhdGVnb3J5ID09PSAnQ291cnNlIEFzc2Vzc21lbnQnIHx8XHJcbiAgICAgICAgaXRlbS5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5zdW5iaXJkLnF1ZXN0aW9uc2V0JyB8fFxyXG4gICAgICAgIGl0ZW0ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9xdWl6JyB8fFxyXG4gICAgICAgIChpdGVtLm5hbWUgJiYgaXRlbS5uYW1lLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoJ2Fzc2Vzc21lbnQnKSlcclxuICAgICAgaWYgKGlzSXRlbUFzc2Vzc21lbnQpIGNvbnRpbnVlXHJcblxyXG4gICAgICAvLyBDaGVjayBpZiB0aGlzIGNvbnRlbnQgaXMgbWFuZGF0b3J5IChjb3Vyc2VzIGFuZCBub24tb3B0aW9uYWwgY29udGVudClcclxuICAgICAgLy8gQnkgZGVmYXVsdCwgY291cnNlcyBhcmUgbWFuZGF0b3J5IHVubGVzcyBleHBsaWNpdGx5IG1hcmtlZCBvdGhlcndpc2VcclxuICAgICAgaWYgKGl0ZW0uaXNNYW5kYXRvcnkgIT09IGZhbHNlICYmIChpdGVtLnByaW1hcnlDYXRlZ29yeSA9PT0gJ0NvdXJzZScgfHwgaXRlbS5pc01hbmRhdG9yeSA9PT0gdHJ1ZSkpIHtcclxuICAgICAgICAvLyBDb3VudCBhbGwgY291cnNlcyBhbmQgbWFuZGF0b3J5IGl0ZW1zIGFzIHRoZXkgbmVlZCB0byBiZSBjb21wbGV0ZWRcclxuICAgICAgICBtYW5kYXRvcnlDb3VudCsrXHJcbiAgICAgICAgY29uc3QgaXNDb21wbGV0ZWQgPSBpdGVtLmNvbXBsZXRpb25TdGF0dXMgPT09IDIgfHwgaXRlbS5zdGF0dXMgPT09IDIgfHwgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0uY29tcGxldGlvblBlcmNlbnRhZ2UgPj0gMTAwIHx8IGl0ZW0ucHJvZ3Jlc3MgPj0gMTAwXHJcbiAgICAgICAgaWYgKGlzQ29tcGxldGVkKSB7XHJcbiAgICAgICAgICBjb21wbGV0ZWRNYW5kYXRvcnlDb3VudCsrXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gSWYgdGhlcmUgYXJlIG5vIG1hbmRhdG9yeSBpdGVtcywgYXNzZXNzbWVudCBpcyB1bmxvY2tlZFxyXG4gICAgaWYgKG1hbmRhdG9yeUNvdW50ID09PSAwKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZVxyXG4gICAgfVxyXG5cclxuICAgIC8vIExvY2sgYXNzZXNzbWVudCBpZiBub3QgYWxsIG1hbmRhdG9yeSBpdGVtcyBhcmUgY29tcGxldGVkXHJcbiAgICBjb25zdCBhbGxNYW5kYXRvcnlDb21wbGV0ZSA9IGNvbXBsZXRlZE1hbmRhdG9yeUNvdW50ID49IG1hbmRhdG9yeUNvdW50XHJcbiAgICByZXR1cm4gIWFsbE1hbmRhdG9yeUNvbXBsZXRlXHJcbiAgfVxyXG5cclxuICAvLyBGT1IgUklHSFQgU0lERSBSRVNPVVJDRSBTQ1JPTEwgT04gVE9DIFBBR0VcclxuICByZXNvdXJjZVNjcm9sbCgpIHtcclxuICAgIHRoaXMucGFnZVNjcm9sbFN1YnNjcmlwdGlvbiA9IHRoaXMuYXBwVG9jU3ZjLnVwZGF0ZVBhZ2VTY3JvbGwuc3Vic2NyaWJlKCh2YWx1ZTogYm9vbGVhbikgPT4ge1xyXG4gICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgIHRoaXMuc2Nyb2xsVmlldygpXHJcbiAgICAgICAgfSwgNzAwKVxyXG4gICAgICB9XHJcbiAgICB9KVxyXG4gIH1cclxuICAvLyBUTyBVUERBVEUgUkVTT1VSQ0UgQkVIQVZPVVIgU1VCSkVDVCBGT1IgUkVTT1VSQ0UgU0NST0xMXHJcbiAgY2hhbmdlUmVzb3VyY2UoKSB7XHJcbiAgICB0aGlzLmFwcFRvY1N2Yy5nZXRQYWdlU2Nyb2xsLm5leHQodHJ1ZSlcclxuICB9XHJcblxyXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcclxuICAgIGxldCBzaG91bGRSZWNvbXB1dGVDYWNoZSA9IGZhbHNlXHJcblxyXG4gICAgZm9yIChjb25zdCBwcm9wZXJ0eSBpbiBjaGFuZ2VzKSB7XHJcbiAgICAgIGlmIChwcm9wZXJ0eSA9PT0gJ2V4cGFuZEFsbCcpIHtcclxuICAgICAgICB0aGlzLnZpZXdDaGlsZHJlbiA9IHRoaXMuZXhwYW5kQWxsXHJcbiAgICAgIH1cclxuICAgICAgaWYgKHByb3BlcnR5ID09PSAncGF0aFNldCcgJiYgY2hhbmdlc1sncGF0aFNldCddKSB7XHJcbiAgICAgICAgbGV0IGN1cnJlbnRWYWx1ZSA9IGNoYW5nZXNbJ3BhdGhTZXQnXS5jdXJyZW50VmFsdWVcclxuICAgICAgICBsZXQgcHJldmlvdXNWYWx1ZSA9IGNoYW5nZXNbJ3BhdGhTZXQnXS5wcmV2aW91c1ZhbHVlXHJcbiAgICAgICAgaWYgKGN1cnJlbnRWYWx1ZSAmJiBwcmV2aW91c1ZhbHVlKSB7XHJcbiAgICAgICAgICBjb25zdCBlcVNldCA9ICh4czogYW55LCB5czogYW55KSA9PlxyXG4gICAgICAgICAgICB4cy5zaXplID09PSB5cy5zaXplICYmXHJcbiAgICAgICAgICAgIFsuLi54c10uZXZlcnkoKHgpID0+IHlzLmhhcyh4KSlcclxuICAgICAgICAgIGlmICghZXFTZXQocHJldmlvdXNWYWx1ZSwgY3VycmVudFZhbHVlKSkgeyB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGlmKHByZXZpb3VzVmFsdWUgPT09IHVuZGVmaW5lZCl7XHJcbiAgICAgICAgLy8gICBzZXRUaW1lb3V0KCgpPT57XHJcbiAgICAgICAgLy8gICB9LDcwMClcclxuICAgICAgICAvLyB9XHJcbiAgICAgIH1cclxuICAgICAgLy8gdGhpcy5hcHBUb2NTdmMuZ2V0UGFnZVNjcm9sbC5uZXh0KHRydWUpXHJcblxyXG4gICAgICBpZiAocHJvcGVydHkgPT09ICdoaWVyYXJjaHlNYXBEYXRhJykge1xyXG4gICAgICAgIGlmIChfLmlzRW1wdHkoY2hhbmdlc1snaGllcmFyY2h5TWFwRGF0YSddLmN1cnJlbnRWYWx1ZSkpIHtcclxuICAgICAgICAgIC8vIHRoaXMubG9hZGluZ092ZXJhbGxQUm9ncmVzcyA9IHRydWVcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgaWYgKHRoaXMuY29udGVudCkge1xyXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUNoaWxkUGFyZW50TWFwKHRoaXMuY29udGVudC5pZGVudGlmaWVyKVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgc2hvdWxkUmVjb21wdXRlQ2FjaGUgPSB0cnVlXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBSZWNvbXB1dGUgY2FjaGUgd2hlbiBjcml0aWNhbCBpbnB1dHMgY2hhbmdlXHJcbiAgICAgIGlmIChwcm9wZXJ0eSA9PT0gJ2NvbnRlbnQnIHx8IHByb3BlcnR5ID09PSAnYmFzZUNvbnRlbnRSZWFkRGF0YScgfHwgXHJcbiAgICAgICAgICBwcm9wZXJ0eSA9PT0gJ2JhdGNoSWQnIHx8IHByb3BlcnR5ID09PSAnZm9yUHJldmlldycgfHwgXHJcbiAgICAgICAgICBwcm9wZXJ0eSA9PT0gJ3BhcmVudE1pbGVzdG9uZUxvY2tlZCcgfHwgcHJvcGVydHkgPT09ICdtbENvdXJzZScpIHtcclxuICAgICAgICBzaG91bGRSZWNvbXB1dGVDYWNoZSA9IHRydWVcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIFJlY29tcHV0ZSBhbGwgY2FjaGVkIHByb3BlcnRpZXMgaWYgbmVlZGVkXHJcbiAgICBpZiAoc2hvdWxkUmVjb21wdXRlQ2FjaGUpIHtcclxuICAgICAgdGhpcy5jb21wdXRlQWxsQ2FjaGVkUHJvcGVydGllcygpXHJcbiAgICB9XHJcbiAgICAvLyBjb25zb2xlLmxvZygncHJlIGFzc2Vzc21lbnQgY29udGVudC0tLScsIHRoaXMuY29udGVudClcclxuICAgIC8vIGNvbnNvbGUubG9nKCd0aGlzLmhpZXJhcmNoeU1hcERhdGEtLS0nLCB0aGlzLmhpZXJhcmNoeU1hcERhdGEpXHJcbiAgfVxyXG5cclxuICBjaGVjayhjb250ZW50OiBhbnkpIHtcclxuICAgIGlmICh0aGlzLmV4cGFuZEFjdGl2ZSkge1xyXG4gICAgICBjb250ZW50LnZpZXdDaGlsZHJlbiA9IHRoaXMucGF0aFNldCAmJiB0aGlzLnBhdGhTZXQuaGFzKGNvbnRlbnQuaWRlbnRpZmllcikgfHwgY29udGVudC52aWV3Q2hpbGRyZW5cclxuICAgIH1cclxuICAgIHJldHVybiBjb250ZW50LnZpZXdDaGlsZHJlblxyXG4gIH1cclxuXHJcbiAgZ2V0IGlzQ29sbGVjdGlvbigpOiBib29sZWFuIHtcclxuICAgIGlmICh0aGlzLl9jYWNoZUluaXRpYWxpemVkKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9jYWNoZWRJc0NvbGxlY3Rpb25cclxuICAgIH1cclxuICAgIGlmICh0aGlzLmNvbnRlbnQpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuY29udGVudC5taW1lVHlwZSA9PT0gTnNDb250ZW50LkVNaW1lVHlwZXMuQ09MTEVDVElPTlxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGZhbHNlXHJcbiAgfVxyXG5cclxuICBnZXQgaXNNb2R1bGUoKTogYm9vbGVhbiB7XHJcbiAgICBpZiAodGhpcy5fY2FjaGVJbml0aWFsaXplZCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5fY2FjaGVkSXNNb2R1bGVcclxuICAgIH1cclxuICAgIGlmICh0aGlzLmNvbnRlbnQpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk1PRFVMRVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGZhbHNlXHJcbiAgfVxyXG5cclxuICBwdWJsaWMgY2hlY2tNb2R1bGUoY29udGVudDogTnNDb250ZW50LklDb250ZW50IHwgbnVsbCk6IGJvb2xlYW4ge1xyXG4gICAgaWYgKGNvbnRlbnQpIHtcclxuICAgICAgcmV0dXJuIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5NT0RVTEVcclxuICAgIH1cclxuICAgIHJldHVybiBmYWxzZVxyXG4gIH1cclxuXHJcbiAgY2hlY2tJc01vZHVsZShjb250ZW50OiBhbnkpOiBib29sZWFuIHtcclxuICAgIGlmIChjb250ZW50KSB7XHJcbiAgICAgIHJldHVybiBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuTU9EVUxFXHJcbiAgICB9XHJcbiAgICByZXR1cm4gZmFsc2VcclxuICB9XHJcblxyXG4gIGdldCBpc0JhdGNoSW5Qcm9nZXNzKCkge1xyXG4gICAgaWYgKHRoaXMuYmF0Y2hEYXRhICYmICh0aGlzLmJhdGNoRGF0YS5jb250ZW50ICYmIHRoaXMuYmF0Y2hEYXRhLmNvbnRlbnQubGVuZ3RoKSAmJiB0aGlzLmJhdGNoRGF0YS5lbnJvbGxlZCkge1xyXG4gICAgICBjb25zdCBiYXRjaERhdGEgPSB0aGlzLmJhdGNoRGF0YS5jb250ZW50WzBdXHJcbiAgICAgIGlmIChiYXRjaERhdGEgJiYgYmF0Y2hEYXRhLmVuZERhdGUpIHtcclxuICAgICAgICBjb25zdCBub3cgPSBtb21lbnQoKS5mb3JtYXQoJ1lZWVktTU0tREQnKVxyXG4gICAgICAgIGNvbnN0IHN0YXJ0RGF0ZSA9IG1vbWVudChiYXRjaERhdGEuc3RhcnREYXRlKS5mb3JtYXQoJ1lZWVktTU0tREQnKVxyXG4gICAgICAgIGNvbnN0IGVuZERhdGUgPSBiYXRjaERhdGEuZW5kRGF0ZSA/IG1vbWVudChiYXRjaERhdGEuZW5kRGF0ZSkuZm9ybWF0KCdZWVlZLU1NLUREJykgOiBub3dcclxuICAgICAgICByZXR1cm4gKFxyXG4gICAgICAgICAgLy8gYmF0Y2guc3RhdHVzICYmXHJcbiAgICAgICAgICBtb21lbnQoc3RhcnREYXRlKS5pc1NhbWVPckJlZm9yZShub3cpXHJcbiAgICAgICAgICAmJiBtb21lbnQoZW5kRGF0ZSkuaXNTYW1lT3JBZnRlcihub3cpXHJcbiAgICAgICAgKVxyXG4gICAgICB9IHJldHVybiB0cnVlXHJcbiAgICB9XHJcbiAgICByZXR1cm4gZmFsc2VcclxuICB9XHJcblxyXG4gIGdldCBpc1Jlc291cmNlKCk6IGJvb2xlYW4ge1xyXG4gICAgaWYgKHRoaXMuX2NhY2hlSW5pdGlhbGl6ZWQpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZElzUmVzb3VyY2VcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLmNvbXB1dGVJc1Jlc291cmNlKClcclxuICB9XHJcblxyXG4gIGdldCByZXNvdXJjZUxpbmsoKTogeyB1cmw6IHN0cmluZzsgcXVlcnlQYXJhbXM6IHsgW2tleTogc3RyaW5nXTogYW55IH0gfSB7XHJcbiAgICBpZiAodGhpcy5fY2FjaGVJbml0aWFsaXplZCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5fY2FjaGVkUmVzb3VyY2VMaW5rXHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5jb21wdXRlUmVzb3VyY2VMaW5rKClcclxuICB9XHJcblxyXG4gIHB1YmxpYyBwcm9ncmVzc0NvbG9yKCk6IHN0cmluZyB7XHJcbiAgICAvLyBpZiAodGhpcy5jdXJyZW50UHJvZ3Jlc3MgPD0gMzApIHtcclxuICAgIC8vICAgcmV0dXJuICcjRDEzOTI0J1xyXG4gICAgLy8gfSBpZiAodGhpcy5jdXJyZW50UHJvZ3Jlc3MgPiAzMCAmJiB0aGlzLmN1cnJlbnRQcm9ncmVzcyA8PSA3MCkge1xyXG4gICAgLy8gICByZXR1cm4gJyNFOTlFMzgnXHJcbiAgICAvLyB9XHJcbiAgICAvLyBpZiAodGhpcy5jdXJyZW50UHJvZ3Jlc3MgPiA3MCAmJiB0aGlzLmN1cnJlbnRQcm9ncmVzcyA8PSAxMDApIHtcclxuICAgIC8vICAgcmV0dXJuICcjMUQ4OTIzJ1xyXG4gICAgLy8gfVxyXG5cclxuICAgIHJldHVybiAnIzFEODkyMydcclxuICB9XHJcbiAgcHVibGljIHByb2dyZXNzQ29sb3IyKCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gJyNmMjdkMDAnXHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGV2YWx1YXRlSW1tZWRpYXRlQ2hpbGRyZW5TdHJ1Y3R1cmUoKSB7XHJcbiAgICBpZiAodGhpcy5jb250ZW50ICYmIHRoaXMuY29udGVudC5jaGlsZHJlbiAmJiB0aGlzLmNvbnRlbnQuY2hpbGRyZW4ubGVuZ3RoKSB7XHJcbiAgICAgIHRoaXMuY29udGVudC5jaGlsZHJlbi5mb3JFYWNoKChjaGlsZDogTnNDb250ZW50LklDb250ZW50KSA9PiB7XHJcbiAgICAgICAgaWYgKGNoaWxkLnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuQ09VUlNFKSB7XHJcbiAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUuY291cnNlICs9IDFcclxuICAgICAgICB9IGVsc2UgaWYgKGNoaWxkLnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuS05PV0xFREdFX0FSVElGQUNUKSB7XHJcbiAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUub3RoZXIgKz0gMVxyXG4gICAgICAgIH0gZWxzZSBpZiAoY2hpbGQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5NT0RVTEUpIHtcclxuICAgICAgICAgIHRoaXMuY29udGVudFN0cnVjdHVyZS5sZWFybmluZ01vZHVsZSArPSAxXHJcbiAgICAgICAgfSBlbHNlIGlmIChjaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk9GRkxJTkVfU0VTU0lPTikge1xyXG4gICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLm9mZmxpbmVTZXNzaW9uICs9IDFcclxuICAgICAgICB9IGVsc2UgaWYgKGNoaWxkLnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuUkVTT1VSQ0UpIHtcclxuICAgICAgICAgIHN3aXRjaCAoY2hpbGQubWltZVR5cGUpIHtcclxuICAgICAgICAgICAgY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5IQU5EU19PTjpcclxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUuaGFuZHNPbiArPSAxXHJcbiAgICAgICAgICAgICAgYnJlYWtcclxuICAgICAgICAgICAgY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5NUDM6XHJcbiAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLnBvZGNhc3QgKz0gMVxyXG4gICAgICAgICAgICAgIGJyZWFrXHJcbiAgICAgICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuTVA0OlxyXG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLk0zVTg6XHJcbiAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLnZpZGVvICs9IDFcclxuICAgICAgICAgICAgICBicmVha1xyXG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLklOVEVSQUNUSU9OOlxyXG4gICAgICAgICAgICAgIHRoaXMuY29udGVudFN0cnVjdHVyZS5pbnRlcmFjdGl2ZVZpZGVvICs9IDFcclxuICAgICAgICAgICAgICBicmVha1xyXG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLlBERjpcclxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUucGRmICs9IDFcclxuICAgICAgICAgICAgICBicmVha1xyXG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLk9GRkxJTkVfU0VTU0lPTjpcclxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUub2ZmbGluZVNlc3Npb24gKz0gMVxyXG4gICAgICAgICAgICAgIGJyZWFrXHJcbiAgICAgICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuU1VSVkVZOlxyXG4gICAgICAgICAgICAgIHRoaXMuY29udGVudFN0cnVjdHVyZS5zdXJ2ZXkgKz0gMVxyXG4gICAgICAgICAgICAgIGJyZWFrXHJcbiAgICAgICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuSFRNTDpcclxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUud2ViUGFnZSArPSAxXHJcbiAgICAgICAgICAgICAgYnJlYWtcclxuICAgICAgICAgICAgY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5RVUlaOlxyXG4gICAgICAgICAgICAgIGlmIChjaGlsZC5yZXNvdXJjZVR5cGUgPT09ICdBc3Nlc3NtZW50Jykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLmFzc2Vzc21lbnQgKz0gMVxyXG4gICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUucXVpeiArPSAxXHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIGJyZWFrXHJcbiAgICAgICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuUFJBQ1RJQ0VfUkVTT1VSQ0U6XHJcbiAgICAgICAgICAgICAgLy8gY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5GSU5BTF9BU1NFU1NNRU5UOlxyXG4gICAgICAgICAgICAgIC8vIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuUFJBQ1RJQ0VfUkVTT1VSQ0U6XHJcbiAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLnByYWN0aWNlVGVzdCArPSAxXHJcbiAgICAgICAgICAgICAgYnJlYWtcclxuICAgICAgICAgICAgY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5XRUJfTU9EVUxFOlxyXG4gICAgICAgICAgICAgIHRoaXMuY29udGVudFN0cnVjdHVyZS53ZWJNb2R1bGUgKz0gMVxyXG4gICAgICAgICAgICAgIGJyZWFrXHJcbiAgICAgICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuWU9VVFVCRTpcclxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUueW91dHViZSArPSAxXHJcbiAgICAgICAgICAgICAgYnJlYWtcclxuICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUub3RoZXIgKz0gMVxyXG4gICAgICAgICAgICAgIGJyZWFrXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9KVxyXG4gICAgfVxyXG4gICAgZm9yIChjb25zdCBrZXkgaW4gdGhpcy5jb250ZW50U3RydWN0dXJlKSB7XHJcbiAgICAgIGlmICh0aGlzLmNvbnRlbnRTdHJ1Y3R1cmVba2V5XSA+IDApIHtcclxuICAgICAgICB0aGlzLmhhc0NvbnRlbnRTdHJ1Y3R1cmUgPSB0cnVlXHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldCBjb250ZXh0UGF0aCgpIHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgIGNvbnRleHRJZDogdGhpcy5yb290SWQsXHJcbiAgICAgIGNvbnRleHRQYXRoOiB0aGlzLnJvb3RDb250ZW50VHlwZSxcclxuICAgICAgYmF0Y2hJZDogdGhpcy5iYXRjaElkLFxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHVibGljIGNvbnRlbnRUcmFja0J5KF9pbmRleDogbnVtYmVyLCBjb250ZW50OiBOc0NvbnRlbnQuSUNvbnRlbnQpIHtcclxuICAgIGlmICghY29udGVudCkge1xyXG4gICAgICByZXR1cm4gbnVsbFxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGNvbnRlbnQuaWRlbnRpZmllclxyXG4gIH1cclxuXHJcbiAgcHVibGljIHJhaXNlVGVsZW1ldHJ5KCkge1xyXG4gICAgLy8gaWYgKHRoaXMuZm9yUHJldmlldykgeyByZXR1cm4gfVxyXG4gICAgaWYgKHRoaXMuY29udGVudCkge1xyXG4gICAgICB0aGlzLmV2ZW50cy5yYWlzZUludGVyYWN0VGVsZW1ldHJ5KFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHR5cGU6ICdjbGljaycsXHJcbiAgICAgICAgICBzdWJUeXBlOiBgY2FyZC10b2NDb250ZW50Q2FyZGAsXHJcbiAgICAgICAgICAvLyBpZDogdGhpcy5jb250ZW50LmlkZW50aWZpZXIgfHwgJycsXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICAvLyBjb250ZW50SWQ6IHRoaXMuY29udGVudC5pZGVudGlmaWVyIHx8ICcnLFxyXG4gICAgICAgICAgLy8gY29udGVudFR5cGU6IHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnksXHJcbiAgICAgICAgICBpZDogdGhpcy5jb250ZW50LmlkZW50aWZpZXIgfHwgJycsXHJcbiAgICAgICAgICB0eXBlOiB0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5LFxyXG4gICAgICAgICAgcm9sbHVwOiB7XHJcbiAgICAgICAgICAgIGwxOiB0aGlzLnJvb3RJZCB8fCAnJyxcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICB2ZXI6IGAke3RoaXMuY29udGVudC52ZXJzaW9ufSR7Jyd9YCxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHBhZ2VJZEV4dDogYCR7Xy5jYW1lbENhc2UodGhpcy5jb250ZW50LnByaW1hcnlDYXRlZ29yeSl9LWNhcmRgLFxyXG4gICAgICAgICAgbW9kdWxlOiBfLmNhbWVsQ2FzZSh0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5KSxcclxuICAgICAgICB9KVxyXG4gICAgfVxyXG4gIH1cclxuICBnZXQgaXNBbGxvd2VkKCk6IGJvb2xlYW4ge1xyXG4gICAgaWYgKHRoaXMuY29udGVudCkge1xyXG4gICAgICByZXR1cm4gIShOc0NvbnRlbnQuVU5fU1VQUE9SVEVEX0RBVEFfVFlQRVNfRk9SX05PTl9CQVRDSF9VU0VSUy5pbmRleE9mKHRoaXMuY29udGVudC5taW1lVHlwZSkgPj0gMClcclxuICAgIH0gcmV0dXJuIGZhbHNlXHJcbiAgfVxyXG5cclxuICBnZXQgaXNFbmFibGVkKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRydWVcclxuICB9XHJcblxyXG4gIGdldCBpc0Vucm9sbGVkKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuYmF0Y2hJZCA/IHRydWUgOiBmYWxzZVxyXG4gIH1cclxuXHJcbiAgdXBkYXRlQ2hpbGRQYXJlbnRNYXAoaWRlbnRpZmllcjogc3RyaW5nKSB7XHJcbiAgICBpZiAodGhpcy5oaWVyYXJjaHlNYXBEYXRhICYmIHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXSkge1xyXG4gICAgICBsZXQgbG9jYWxDb250ZW50RGF0YSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXVxyXG4gICAgICBpZiAoXHJcbiAgICAgICAgIShsb2NhbENvbnRlbnREYXRhLnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuUkVTT1VSQ0VcclxuICAgICAgICAgIHx8IGxvY2FsQ29udGVudERhdGEucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5QUkFDVElDRV9SRVNPVVJDRVxyXG4gICAgICAgICAgfHwgbG9jYWxDb250ZW50RGF0YS5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlRcclxuICAgICAgICAgIHx8IGxvY2FsQ29udGVudERhdGEucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5DT01QX0FTU0VTU01FTlQpXHJcbiAgICAgICkge1xyXG4gICAgICAgIC8vIHJlYWwgcGVyY2VudCBsb2dpY1xyXG4gICAgICAgIC8vIGNvbnN0IHRvdGFsID0gbG9jYWxDb250ZW50RGF0YS5sZWFmTm9kZXMucmVkdWNlKChzdW06IG51bWJlciwgY2hpbGRJZDogc3RyaW5nKSA9PiB7XHJcbiAgICAgICAgLy8gICByZXR1cm4gc3VtICsgTnVtYmVyKHRoaXMuaGllcmFyY2h5TWFwRGF0YVtjaGlsZElkXS5jb21wbGV0aW9uUGVyY2VudGFnZSB8fCAwKVxyXG4gICAgICAgIC8vIH0sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKVxyXG4gICAgICAgIC8vIGNvbnNvbGUubG9nKCd0b3RhbCAnLCB0b3RhbClcclxuICAgICAgICAvLyBpZih0b3RhbCA+IDApIHtcclxuICAgICAgICAvLyAgIHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXVsnY29tcGxldGlvblBlcmNlbnRhZ2UnXSA9IHRvdGFsIC8gXy50b0ludGVnZXIoXy5nZXQodGhpcy5oaWVyYXJjaHlNYXBEYXRhW2lkZW50aWZpZXJdLCAnbGVhZk5vZGVzQ291bnQnKSlcclxuICAgICAgICAvLyB9XHJcbiAgICAgICAgaWYgKGxvY2FsQ29udGVudERhdGEucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5NT0RVTEUpIHtcclxuICAgICAgICAgIHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXVsnZHVyYXRpb24nXSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXS5sZWFmTm9kZXMucmVkdWNlKFxyXG4gICAgICAgICAgICAoc3VtOiBhbnksIGNoaWxkSUQ6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgIGlmICh0aGlzLmhpZXJhcmNoeU1hcERhdGEgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2NoaWxkSURdKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gc3VtICsgTnVtYmVyKHRoaXMuaGllcmFyY2h5TWFwRGF0YVtjaGlsZElEXS5kdXJhdGlvbiB8fCB0aGlzLmhpZXJhcmNoeU1hcERhdGFbY2hpbGRJRF0uZXhwZWN0ZWREdXJhdGlvbiB8fCAwKVxyXG4gICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIH0sIDApXHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlXHJcbiAgICAgICAgY29uc3QgY29tcGxldGVkSXRlbXMgPSBfLmZpbHRlcih0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl0ubGVhZk5vZGVzLCByID0+ICh0aGlzLmhpZXJhcmNoeU1hcERhdGFbcl0gJiYgKHRoaXMuaGllcmFyY2h5TWFwRGF0YVtyXS5jb21wbGV0aW9uU3RhdHVzID09PSAyIHx8IHRoaXMuaGllcmFyY2h5TWFwRGF0YVtyXS5jb21wbGV0aW9uUGVyY2VudGFnZSA9PT0gMTAwKSkpXHJcbiAgICAgICAgY29uc3QgdG90YWxDb3VudCA9IF8udG9JbnRlZ2VyKF8uZ2V0KHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXSwgJ2xlYWZOb2Rlc0NvdW50JykpIHx8IDFcclxuICAgICAgICB0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl1bJ2NvbXBsZXRpb25QZXJjZW50YWdlJ10gPSBOdW1iZXIoKChjb21wbGV0ZWRJdGVtcy5sZW5ndGggLyB0b3RhbENvdW50KSAqIDEwMCkudG9GaXhlZCgpKVxyXG4gICAgICAgIHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXVsnY29tcGxldGlvblN0YXR1cyddID0gKHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXS5jb21wbGV0aW9uUGVyY2VudGFnZSA+PSAxMDApID8gMiA6IDFcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2lkZW50aWZpZXJdXHJcbiAgICB9XHJcbiAgICByZXR1cm4gJydcclxuICB9XHJcblxyXG4gIGdldENvbXBsZXRpb25QZXJjZW50YWdlKGlkZW50aWZpZXI6IHN0cmluZykge1xyXG4gICAgLy8gY29uc29sZS5sb2coJ2dldENvbXBsZXRpb25QZXJjZW50YWdlJywgaWRlbnRpZmllcilcclxuICAgIC8vIGNvbnNvbGUubG9nKCd0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl0gOiAnLCB0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl0pXHJcbiAgICAvLyBjb25zdCBpdGVtID0gdGhpcy51cGRhdGVDaGlsZFBhcmVudE1hcChpZGVudGlmaWVyKVxyXG4gICAgbGV0IHBlcmNlbnQgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGEgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2lkZW50aWZpZXJdICYmIHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXS5jb21wbGV0aW9uUGVyY2VudGFnZSB8fCAwXHJcbiAgICByZXR1cm4gdGhpcy5yb3VuZElmRGVjaW1hbChwZXJjZW50KVxyXG4gIH1cclxuXHJcbiAgcm91bmRJZkRlY2ltYWwodmFsdWU6IG51bWJlcik6IG51bWJlciB7XHJcbiAgICBpZiAoIU51bWJlci5pc0ludGVnZXIodmFsdWUpKSB7XHJcbiAgICAgIHJldHVybiBwYXJzZUZsb2F0KHZhbHVlLnRvRml4ZWQoMikpXHJcbiAgICB9XHJcbiAgICByZXR1cm4gdmFsdWVcclxuICB9XHJcblxyXG5cclxuICBnZXRDb21wbGV0aW9uU3RhdHVzKGlkZW50aWZpZXI6IHN0cmluZykge1xyXG4gICAgLy8gY29uc29sZS5sb2coJ2dldENvbXBsZXRpb25TdGF0dXMnKVxyXG4gICAgLy8gY29uc3QgaXRlbSA9IHRoaXMudXBkYXRlQ2hpbGRQYXJlbnRNYXAoaWRlbnRpZmllcilcclxuICAgIHJldHVybiB0aGlzLmhpZXJhcmNoeU1hcERhdGEgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2lkZW50aWZpZXJdICYmIHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXS5jb21wbGV0aW9uU3RhdHVzXHJcbiAgfVxyXG5cclxuICBvcGVuQ2VydGlmaWNhdGVEaWFsb2coY2VydERhdGE6IGFueSkge1xyXG4gICAgY29uc3QgY2V0ID0gY2VydERhdGFcclxuICAgIHRoaXMuZGlhbG9nLm9wZW4oQ2VydGlmaWNhdGVEaWFsb2dDb21wb25lbnQsIHtcclxuICAgICAgLy8gaGVpZ2h0OiAnNDAwcHgnLFxyXG4gICAgICB3aWR0aDogJzEzMDBweCcsXHJcbiAgICAgIGRhdGE6IHsgY2V0IH0sXHJcbiAgICAgIC8vIHBhbmVsQ2xhc3M6ICdjdXN0b20tZGlhbG9nLWNvbnRhaW5lcicsXHJcbiAgICB9KVxyXG4gIH1cclxuICBzY3JvbGxWaWV3KCkge1xyXG4gICAgdHJ5IHtcclxuICAgICAgbGV0IGVycm9yRmllbGQ6IGFueSA9IHRoaXMucmVuZGVyZXIuc2VsZWN0Um9vdEVsZW1lbnQoJy5yZXNvdXJjZS1jb250YWluZXIgLnJlc291cmNlLWFjdGl2ZScpXHJcbiAgICAgIGlmIChlcnJvckZpZWxkKSB7XHJcbiAgICAgICAgZXJyb3JGaWVsZC5zY3JvbGxJbnRvVmlldyh7IGJlaGF2aW9yOiBcInNtb290aFwiLCBibG9jazogXCJzdGFydFwiLCBpbmxpbmU6IFwibmVhcmVzdFwiIH0pXHJcbiAgICAgIH1cclxuICAgICAgaWYgKHRoaXMuY29tcG9uZW50TmFtZSA9PT0gJ3RvYycpIHtcclxuICAgICAgICBpZiAoZXJyb3JGaWVsZCkge1xyXG4gICAgICAgICAgY29uc3QgcmVjdCA9IGVycm9yRmllbGQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcclxuICAgICAgICAgIGlmIChyZWN0LnRvcCAtIDQyMCA+IDApIHtcclxuICAgICAgICAgICAgd2luZG93LnNjcm9sbCg0MjAsIHJlY3QudG9wIC0gMTQ4KVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICB0aGlzLmFwcFRvY1N2Yy5nZXRQYWdlU2Nyb2xsLm5leHQoZmFsc2UpXHJcbiAgICAgIH0sIDcwMClcclxuXHJcbiAgICAgIC8vIGVsc2Uge1xyXG4gICAgICAvLyAgIGVycm9yRmllbGQuc2Nyb2xsSW50b1ZpZXcoeyBiZWhhdmlvcjogXCJzbW9vdGhcIiwgYmxvY2s6IFwic3RhcnRcIiwgaW5saW5lOiBcIm5lYXJlc3RcIiB9KTtcclxuICAgICAgLy8gICBjb25zdCByZWN0ID0gZXJyb3JGaWVsZC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgICAgLy8gICBlcnJvckZpZWxkLnNjcm9sbCgwLHJlY3QudG9wLTU2KVxyXG4gICAgICAvLyB9XHJcbiAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGRvd25sb2FkQ2VydGlmaWNhdGUoY2VydGlmaWNhdGVEYXRhOiBhbnkpIHtcclxuICAgIHRoaXMuZXZlbnRzLnJhaXNlSW50ZXJhY3RUZWxlbWV0cnkoXHJcbiAgICAgIHtcclxuICAgICAgICB0eXBlOiBXc0V2ZW50cy5FbnVtSW50ZXJhY3RUeXBlcy5DTElDSyxcclxuICAgICAgICBpZDogJ3ZpZXctY2VydGlmaWNhdGUnLFxyXG4gICAgICAgIHN1YlR5cGU6IFdzRXZlbnRzLkVudW1JbnRlcmFjdFN1YlR5cGVzLkNFUlRJRklDQVRFLFxyXG4gICAgICB9LFxyXG4gICAgICB7XHJcbiAgICAgICAgaWQ6IGNlcnRpZmljYXRlRGF0YSwgICAvLyBpZCBvZiB0aGUgY2VydGlmaWNhdGVcclxuICAgICAgICB0eXBlOiBXc0V2ZW50cy5FbnVtSW50ZXJhY3RTdWJUeXBlcy5DRVJUSUZJQ0FURSxcclxuICAgICAgfSlcclxuICAgIGlmIChjZXJ0aWZpY2F0ZURhdGEpIHtcclxuICAgICAgdGhpcy5kb3dubG9hZENlcnRpZmljYXRlTG9hZGluZyA9IHRydWVcclxuICAgICAgbGV0IGNlcnREYXRhOiBhbnkgPSBjZXJ0aWZpY2F0ZURhdGFcclxuICAgICAgdGhpcy5jZXJ0aWZpY2F0ZVNlcnZpY2UuZG93bmxvYWRDZXJ0aWZpY2F0ZV92MihjZXJ0RGF0YSkuc3Vic2NyaWJlKChyZXM6IGFueSkgPT4ge1xyXG4gICAgICAgIHRoaXMuZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmcgPSBmYWxzZVxyXG4gICAgICAgIGNvbnN0IGNldCA9IHJlcy5yZXN1bHQucHJpbnRVcmlcclxuICAgICAgICB0aGlzLmRpYWxvZy5vcGVuKENlcnRpZmljYXRlRGlhbG9nQ29tcG9uZW50LCB7XHJcbiAgICAgICAgICB3aWR0aDogJzEzMDBweCcsXHJcbiAgICAgICAgICBkYXRhOiB7IGNldCwgY2VydElkOiBjZXJ0RGF0YS5pZGVudGlmaWVyIH0sXHJcbiAgICAgICAgfSlcclxuICAgICAgfSlcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmcgPSBmYWxzZVxyXG4gICAgfVxyXG4gIH1cclxuICBuZ09uRGVzdHJveSgpIHtcclxuICAgIGlmICh0aGlzLnBhZ2VTY3JvbGxTdWJzY3JpcHRpb24pIHtcclxuICAgICAgdGhpcy5wYWdlU2Nyb2xsU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKClcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldCBjaGVja0ZvckN1cmF0ZWRQcm9ncmFtKCkge1xyXG4gICAgaWYgKHRoaXMuX2NhY2hlSW5pdGlhbGl6ZWQpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZENoZWNrRm9yQ3VyYXRlZFByb2dyYW1cclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLmNvbXB1dGVDaGVja0ZvckN1cmF0ZWRQcm9ncmFtKClcclxuICB9XHJcblxyXG4gIGdldCBpc0NvbnRlbnRVbmxvY2tlZCgpIHtcclxuICAgIGlmICh0aGlzLl9jYWNoZUluaXRpYWxpemVkKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9jYWNoZWRJc0NvbnRlbnRVbmxvY2tlZFxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuY29tcHV0ZUlzQ29udGVudFVubG9ja2VkKClcclxuICB9XHJcblxyXG4gIGdldCBpc1BhcmVudE1pbGVzdG9uZUxvY2tlZCgpOiBib29sZWFuIHtcclxuICAgIGlmICh0aGlzLl9jYWNoZUluaXRpYWxpemVkKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9jYWNoZWRJc1BhcmVudE1pbGVzdG9uZUxvY2tlZFxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuY29tcHV0ZUlzUGFyZW50TWlsZXN0b25lTG9ja2VkKClcclxuICB9XHJcblxyXG4gIGdldCBpc01pbGVzdG9uZUxvY2tlZCgpOiBib29sZWFuIHtcclxuICAgIGlmICh0aGlzLl9jYWNoZUluaXRpYWxpemVkKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9jYWNoZWRJc01pbGVzdG9uZUxvY2tlZFxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuY29tcHV0ZUlzTWlsZXN0b25lTG9ja2VkKClcclxuICB9XHJcblxyXG4gIGdldCBpc01pbGVzdG9uZUFzc2Vzc21lbnQoKTogYm9vbGVhbiB7XHJcbiAgICBpZiAodGhpcy5fY2FjaGVJbml0aWFsaXplZCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5fY2FjaGVkSXNNaWxlc3RvbmVBc3Nlc3NtZW50XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5jb21wdXRlSXNNaWxlc3RvbmVBc3Nlc3NtZW50KClcclxuICB9XHJcblxyXG4gIGdldCBpc01pbGVzdG9uZUFzc2Vzc21lbnRMb2NrZWQoKTogYm9vbGVhbiB7XHJcbiAgICBpZiAodGhpcy5fY2FjaGVJbml0aWFsaXplZCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5fY2FjaGVkSXNNaWxlc3RvbmVBc3Nlc3NtZW50TG9ja2VkXHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5jb21wdXRlSXNNaWxlc3RvbmVBc3Nlc3NtZW50TG9ja2VkKClcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrIGlmIGEgbWlsZXN0b25lJ3MgbWFuZGF0b3J5IGNvdXJzZXMgYW5kIGFzc2Vzc21lbnQgYXJlIGNvbXBsZXRlZC5cclxuICAgKiBMb29rcyBhdCB0aGUgY29udGVudCBoaWVyYXJjaHkgdG8gZmluZCBjaGlsZHJlbiBvZiB0aGUgbWlsZXN0b25lLlxyXG4gICAqL1xyXG4gIHByaXZhdGUgY2hlY2tNaWxlc3RvbmVDb250ZW50Q29tcGxldGlvbihtaWxlc3RvbmVJZDogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICBpZiAoIXRoaXMuYmFzZUNvbnRlbnRSZWFkRGF0YSB8fCAhdGhpcy5iYXNlQ29udGVudFJlYWREYXRhLmNoaWxkcmVuIHx8ICF0aGlzLmhpZXJhcmNoeU1hcERhdGEpIHtcclxuICAgICAgLy8gRmFsbGJhY2s6IFRyeSB0byBmaW5kIGFzc2Vzc21lbnQgY29tcGxldGlvbiBpbiBoYXNobWFwIGZvciB0aGlzIG1pbGVzdG9uZVxyXG4gICAgICByZXR1cm4gdGhpcy5jaGVja01pbGVzdG9uZUFzc2Vzc21lbnRDb21wbGV0aW9uKG1pbGVzdG9uZUlkKVxyXG4gICAgfVxyXG5cclxuICAgIC8vIEZpbmQgdGhlIG1pbGVzdG9uZSBpbiB0aGUgY29udGVudCBoaWVyYXJjaHlcclxuICAgIGNvbnN0IG1pbGVzdG9uZUNvbnRlbnQgPSB0aGlzLmZpbmRDb250ZW50SW5IaWVyYXJjaHkodGhpcy5iYXNlQ29udGVudFJlYWREYXRhLCBtaWxlc3RvbmVJZClcclxuICAgIGlmICghbWlsZXN0b25lQ29udGVudCB8fCAhbWlsZXN0b25lQ29udGVudC5jaGlsZHJlbikge1xyXG4gICAgICByZXR1cm4gdGhpcy5jaGVja01pbGVzdG9uZUFzc2Vzc21lbnRDb21wbGV0aW9uKG1pbGVzdG9uZUlkKVxyXG4gICAgfVxyXG5cclxuICAgIC8vIENoZWNrIGFsbCBtYW5kYXRvcnkgY291cnNlcyBhbmQgYXNzZXNzbWVudHNcclxuICAgIGxldCBhbGxNYW5kYXRvcnlDb21wbGV0ZSA9IHRydWVcclxuICAgIGxldCBoYXNBc3Nlc3NtZW50ID0gZmFsc2VcclxuICAgIGxldCBhc3Nlc3NtZW50Q29tcGxldGUgPSBmYWxzZVxyXG5cclxuICAgIG1pbGVzdG9uZUNvbnRlbnQuY2hpbGRyZW4uZm9yRWFjaCgoY2hpbGQ6IGFueSkgPT4ge1xyXG4gICAgICBjb25zdCBjaGlsZERhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbY2hpbGQuaWRlbnRpZmllcl1cclxuICAgICAgY29uc3QgaXNBc3Nlc3NtZW50ID0gY2hpbGQucHJpbWFyeUNhdGVnb3J5ID09PSAnQ291cnNlIEFzc2Vzc21lbnQnIHx8XHJcbiAgICAgICAgY2hpbGQuY291cnNlQ2F0ZWdvcnkgPT09ICdDb3Vyc2UgQXNzZXNzbWVudCcgfHxcclxuICAgICAgICBjaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgPT09ICdGaW5hbCBBc3Nlc3NtZW50J1xyXG4gICAgICBjb25zdCBpc01hbmRhdG9yeSA9IGNoaWxkLm1hbmRhdG9yeSA9PT0gdHJ1ZSB8fCBjaGlsZC5vcHRpb25hbFJlYWRpbmcgIT09IHRydWVcclxuXHJcbiAgICAgIGlmIChpc0Fzc2Vzc21lbnQpIHtcclxuICAgICAgICBoYXNBc3Nlc3NtZW50ID0gdHJ1ZVxyXG4gICAgICAgIGlmIChjaGlsZERhdGEgJiYgKGNoaWxkRGF0YS5jb21wbGV0aW9uU3RhdHVzID09PSAyIHx8IGNoaWxkRGF0YS5jb21wbGV0aW9uUGVyY2VudGFnZSA+PSAxMDApKSB7XHJcbiAgICAgICAgICBhc3Nlc3NtZW50Q29tcGxldGUgPSB0cnVlXHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2UgaWYgKGlzTWFuZGF0b3J5KSB7XHJcbiAgICAgICAgLy8gQ2hlY2sgaWYgbWFuZGF0b3J5IGNvbnRlbnQgaXMgY29tcGxldGVkXHJcbiAgICAgICAgaWYgKCFjaGlsZERhdGEgfHwgKGNoaWxkRGF0YS5jb21wbGV0aW9uU3RhdHVzICE9PSAyICYmIGNoaWxkRGF0YS5jb21wbGV0aW9uUGVyY2VudGFnZSA8IDEwMCkpIHtcclxuICAgICAgICAgIGFsbE1hbmRhdG9yeUNvbXBsZXRlID0gZmFsc2VcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0pXHJcblxyXG4gICAgY29uc29sZS5sb2coJ01pbGVzdG9uZSBjb250ZW50IGNoZWNrOicsIHsgYWxsTWFuZGF0b3J5Q29tcGxldGUsIGhhc0Fzc2Vzc21lbnQsIGFzc2Vzc21lbnRDb21wbGV0ZSB9KVxyXG5cclxuICAgIC8vIE1pbGVzdG9uZSBpcyBjb21wbGV0ZSBpZiBhc3Nlc3NtZW50IGlzIGNvbXBsZXRlIChtYW5kYXRvcnkgY291cnNlcyBvcHRpb25hbCBiYXNlZCBvbiByZXF1aXJlbWVudHMpXHJcbiAgICByZXR1cm4gaGFzQXNzZXNzbWVudCA/IGFzc2Vzc21lbnRDb21wbGV0ZSA6IGFsbE1hbmRhdG9yeUNvbXBsZXRlXHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBGYWxsYmFjazogQ2hlY2sgaWYgZW5vdWdoIGFzc2Vzc21lbnRzIGFyZSBjb21wbGV0ZWQgdG8gdW5sb2NrIHRoaXMgbWlsZXN0b25lLlxyXG4gICAqIEZvciBtaWxlc3RvbmUgYXQgaW5kZXggTiwgd2UgbmVlZCBhdCBsZWFzdCBOIGNvbXBsZXRlZCBhc3Nlc3NtZW50cy5cclxuICAgKiBFLmcuLCBGb3IgTTIgKGluZGV4IDEpLCB3ZSBuZWVkIDEgY29tcGxldGVkIGFzc2Vzc21lbnQgKE0xJ3MgYXNzZXNzbWVudClcclxuICAgKiAgICAgICBGb3IgTTMgKGluZGV4IDIpLCB3ZSBuZWVkIDIgY29tcGxldGVkIGFzc2Vzc21lbnRzIChNMSdzIGFuZCBNMidzKVxyXG4gICAqL1xyXG4gIHByaXZhdGUgY2hlY2tNaWxlc3RvbmVBc3Nlc3NtZW50Q29tcGxldGlvbihtaWxlc3RvbmVJZDogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICBpZiAoIXRoaXMuaGllcmFyY2h5TWFwRGF0YSkge1xyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuXHJcbiAgICAvLyBFeHRyYWN0IG1pbGVzdG9uZSBudW1iZXIgZnJvbSBJRCAoTTEgLT4gMSwgTTIgLT4gMiwgZXRjLilcclxuICAgIGNvbnN0IG1pbGVzdG9uZU51bSA9IHBhcnNlSW50KG1pbGVzdG9uZUlkLnJlcGxhY2UoL1xcRC9nLCAnJykpIHx8IDBcclxuICAgIGNvbnN0IHJlcXVpcmVkQ29tcGxldGVkQXNzZXNzbWVudHMgPSBtaWxlc3RvbmVOdW0gLSAxIC8vIEZvciBNMiwgbmVlZCAxOyBmb3IgTTMsIG5lZWQgMlxyXG5cclxuICAgIGNvbnNvbGUubG9nKGBNaWxlc3RvbmUgJHttaWxlc3RvbmVJZH0gKG51bTogJHttaWxlc3RvbmVOdW19KSByZXF1aXJlcyAke3JlcXVpcmVkQ29tcGxldGVkQXNzZXNzbWVudHN9IGNvbXBsZXRlZCBhc3Nlc3NtZW50c2ApXHJcblxyXG4gICAgaWYgKHJlcXVpcmVkQ29tcGxldGVkQXNzZXNzbWVudHMgPD0gMCkge1xyXG4gICAgICByZXR1cm4gdHJ1ZSAvLyBGaXJzdCBtaWxlc3RvbmUsIG5vIHJlcXVpcmVtZW50c1xyXG4gICAgfVxyXG5cclxuICAgIC8vIENvdW50IGNvbXBsZXRlZCBDb3Vyc2UgQXNzZXNzbWVudHMgdGhhdCBhcmUgSU5TSURFIG1pbGVzdG9uZXMgKGhhdmUgYSBwYXJlbnQpXHJcbiAgICAvLyBFeGNsdWRlIHByZS1lbnJvbGxtZW50IGFzc2Vzc21lbnRzIGF0IHRoZSByb290IGxldmVsIChubyBwYXJlbnQgb3IgcGFyZW50IGlzIExlYXJuaW5nIFBhdGh3YXkpXHJcbiAgICBsZXQgY29tcGxldGVkTWlsZXN0b25lQXNzZXNzbWVudENvdW50ID0gMFxyXG4gICAgY29uc3QgbGVhcm5pbmdQYXRod2F5SWQgPSB0aGlzLmJhc2VDb250ZW50UmVhZERhdGE/LmlkZW50aWZpZXJcclxuXHJcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyh0aGlzLmhpZXJhcmNoeU1hcERhdGEpKSB7XHJcbiAgICAgIGNvbnN0IGl0ZW0gPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFba2V5XVxyXG5cclxuICAgICAgLy8gQ2hlY2sgaWYgaXQncyBhIGNvbXBsZXRlZCBDb3Vyc2UgQXNzZXNzbWVudFxyXG4gICAgICBpZiAoKGl0ZW0ucHJpbWFyeUNhdGVnb3J5ID09PSAnQ291cnNlIEFzc2Vzc21lbnQnIHx8IGl0ZW0uY291cnNlQ2F0ZWdvcnkgPT09ICdDb3Vyc2UgQXNzZXNzbWVudCcpICYmXHJcbiAgICAgICAgKGl0ZW0uY29tcGxldGlvblN0YXR1cyA9PT0gMiB8fCBpdGVtLmNvbXBsZXRpb25QZXJjZW50YWdlID49IDEwMCkpIHtcclxuXHJcbiAgICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBhc3Nlc3NtZW50IGhhcyBhIHBhcmVudCAobWVhbmluZyBpdCdzIGluc2lkZSBhIGNvdXJzZS9taWxlc3RvbmUsIG5vdCBhdCByb290IGxldmVsKVxyXG4gICAgICAgIC8vIEFsc28gZXhjbHVkZSBpZiBwYXJlbnQgaXMgdGhlIExlYXJuaW5nIFBhdGh3YXkgaXRzZWxmIChwcmUtZW5yb2xsbWVudCBhc3Nlc3NtZW50KVxyXG4gICAgICAgIGNvbnN0IGhhc1BhcmVudCA9IGl0ZW0ucGFyZW50ICYmIGl0ZW0ucGFyZW50ICE9PSBsZWFybmluZ1BhdGh3YXlJZFxyXG5cclxuICAgICAgICBpZiAoaGFzUGFyZW50KSB7XHJcbiAgICAgICAgICBjb21wbGV0ZWRNaWxlc3RvbmVBc3Nlc3NtZW50Q291bnQrK1xyXG4gICAgICAgICAgY29uc29sZS5sb2coYEZvdW5kIGNvbXBsZXRlZCBNSUxFU1RPTkUgYXNzZXNzbWVudDogJHtrZXl9YCwgaXRlbSlcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgY29uc29sZS5sb2coYFNraXBwaW5nIHJvb3QtbGV2ZWwvcHJlLWVucm9sbG1lbnQgYXNzZXNzbWVudDogJHtrZXl9YClcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBjb25zb2xlLmxvZyhgVG90YWwgY29tcGxldGVkIE1JTEVTVE9ORSBhc3Nlc3NtZW50czogJHtjb21wbGV0ZWRNaWxlc3RvbmVBc3Nlc3NtZW50Q291bnR9LCBSZXF1aXJlZDogJHtyZXF1aXJlZENvbXBsZXRlZEFzc2Vzc21lbnRzfWApXHJcblxyXG4gICAgLy8gSWYgd2UgaGF2ZSBlbm91Z2ggY29tcGxldGVkIG1pbGVzdG9uZSBhc3Nlc3NtZW50cywgdW5sb2NrIHRoaXMgbWlsZXN0b25lXHJcbiAgICByZXR1cm4gY29tcGxldGVkTWlsZXN0b25lQXNzZXNzbWVudENvdW50ID49IHJlcXVpcmVkQ29tcGxldGVkQXNzZXNzbWVudHNcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZmluZENvbnRlbnRJbkhpZXJhcmNoeShjb250ZW50OiBhbnksIGlkZW50aWZpZXI6IHN0cmluZyk6IGFueSB7XHJcbiAgICBpZiAoIWNvbnRlbnQpIHJldHVybiBudWxsXHJcbiAgICBpZiAoY29udGVudC5pZGVudGlmaWVyID09PSBpZGVudGlmaWVyKSByZXR1cm4gY29udGVudFxyXG4gICAgaWYgKGNvbnRlbnQuY2hpbGRyZW4pIHtcclxuICAgICAgZm9yIChjb25zdCBjaGlsZCBvZiBjb250ZW50LmNoaWxkcmVuKSB7XHJcbiAgICAgICAgY29uc3QgZm91bmQgPSB0aGlzLmZpbmRDb250ZW50SW5IaWVyYXJjaHkoY2hpbGQsIGlkZW50aWZpZXIpXHJcbiAgICAgICAgaWYgKGZvdW5kKSByZXR1cm4gZm91bmRcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIG51bGxcclxuICB9XHJcblxyXG4gIGdldCBjb21wdXRlZFF1ZXJ5UGFyYW1zKCkge1xyXG4gICAgaWYgKHRoaXMuaXNBbGxvd2VkICYmICF0aGlzLmZvclByZXZpZXcgJiYgdGhpcy5pc0VuYWJsZWQpIHtcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICAuLi50aGlzLnJlc291cmNlTGluay5xdWVyeVBhcmFtcyxcclxuICAgICAgICBwcmVBc3Nlc3NtZW50OiAndHJ1ZSdcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIG51bGxcclxuICB9XHJcblxyXG4gIGdldCBpc01pbGVzdG9uZSgpOiBib29sZWFuIHtcclxuICAgIGlmICh0aGlzLl9jYWNoZUluaXRpYWxpemVkKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9jYWNoZWRJc01pbGVzdG9uZVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuY29tcHV0ZUlzTWlsZXN0b25lKClcclxuICB9XHJcblxyXG4gIGdldE1pbGVzdG9uZUNvbXBsZXRlZENvdW50KCk6IG51bWJlciB7XHJcbiAgICBpZiAoIXRoaXMuY29udGVudCB8fCAhdGhpcy5oaWVyYXJjaHlNYXBEYXRhKSB7XHJcbiAgICAgIHJldHVybiAwXHJcbiAgICB9XHJcbiAgICBjb25zdCBtaWxlc3RvbmVEYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3RoaXMuY29udGVudC5pZGVudGlmaWVyXVxyXG4gICAgaWYgKCFtaWxlc3RvbmVEYXRhIHx8ICFtaWxlc3RvbmVEYXRhLmxlYWZOb2Rlcykge1xyXG4gICAgICByZXR1cm4gMFxyXG4gICAgfVxyXG4gICAgbGV0IGNvbXBsZXRlZENvdW50ID0gMFxyXG4gICAgbWlsZXN0b25lRGF0YS5sZWFmTm9kZXMuZm9yRWFjaCgobGVhZklkOiBzdHJpbmcpID0+IHtcclxuICAgICAgY29uc3QgbGVhZkRhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbbGVhZklkXVxyXG4gICAgICBpZiAobGVhZkRhdGEgJiYgbGVhZkRhdGEuY29tcGxldGlvblN0YXR1cyA9PT0gMikge1xyXG4gICAgICAgIGNvbXBsZXRlZENvdW50KytcclxuICAgICAgfVxyXG4gICAgfSlcclxuICAgIHJldHVybiBjb21wbGV0ZWRDb3VudFxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IHVubG9jayBjcml0ZXJpYSBtZXNzYWdlIGZvciBsb2NrZWQgbWlsZXN0b25lc1xyXG4gICAqL1xyXG4gIGdldE1pbGVzdG9uZVVubG9ja01lc3NhZ2UoKTogc3RyaW5nIHtcclxuICAgIGlmICghdGhpcy5jb250ZW50IHx8ICF0aGlzLmhpZXJhcmNoeU1hcERhdGEpIHtcclxuICAgICAgcmV0dXJuICcnXHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgbWlsZXN0b25lRGF0YSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YVt0aGlzLmNvbnRlbnQuaWRlbnRpZmllcl1cclxuICAgIGlmICghbWlsZXN0b25lRGF0YSkge1xyXG4gICAgICByZXR1cm4gJydcclxuICAgIH1cclxuXHJcbiAgICAvLyBDaGVjayBpZiBoYXNobWFwIGhhcyBwcmUtY29tcHV0ZWQgdW5sb2NrIG1lc3NhZ2VcclxuICAgIGlmIChtaWxlc3RvbmVEYXRhLnVubG9ja01lc3NhZ2UpIHtcclxuICAgICAgcmV0dXJuIG1pbGVzdG9uZURhdGEudW5sb2NrTWVzc2FnZVxyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IG1pbGVzdG9uZUluZGV4ID0gbWlsZXN0b25lRGF0YS5taWxlc3RvbmVJbmRleFxyXG5cclxuICAgIC8vIE1pbGVzdG9uZSAxIHJlcXVpcmVzIHByZS1hc3Nlc3NtZW50IGNvbXBsZXRpb25cclxuICAgIGlmIChtaWxlc3RvbmVJbmRleCA9PT0gMCkge1xyXG4gICAgICByZXR1cm4gJ0NvbXBsZXRlIHRoZSBwcmVsaW1pbmFyeSBhc3Nlc3NtZW50IHRvIHVubG9jayB0aGlzIG1pbGVzdG9uZSdcclxuICAgIH1cclxuXHJcbiAgICAvLyBPdGhlciBtaWxlc3RvbmVzIHJlcXVpcmUgcHJldmlvdXMgbWlsZXN0b25lIGNvbXBsZXRpb25cclxuICAgIHJldHVybiBgQ29tcGxldGUgYWxsIG1hbmRhdG9yeSBjb250ZW50IGFuZCBhc3Nlc3NtZW50IGluIE1pbGVzdG9uZSAke21pbGVzdG9uZUluZGV4fSB0byB1bmxvY2sgdGhpcyBtaWxlc3RvbmVgXHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgbG9jayBtZXNzYWdlIGZvciBjb250ZW50IGluc2lkZSBsb2NrZWQgbWlsZXN0b25lc1xyXG4gICAqL1xyXG4gIGdldFBhcmVudE1pbGVzdG9uZUxvY2tNZXNzYWdlKCk6IHN0cmluZyB7XHJcbiAgICBpZiAoIXRoaXMuaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQpIHtcclxuICAgICAgcmV0dXJuICcnXHJcbiAgICB9XHJcbiAgICByZXR1cm4gJ1RoaXMgY29udGVudCBpcyBsb2NrZWQuIENvbXBsZXRlIHByZXZpb3VzIG1pbGVzdG9uZSB0byB2aWV3IHRoaXMgY29udGVudC4nXHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgbG9jayBtZXNzYWdlIGZvciBtaWxlc3RvbmUgYXNzZXNzbWVudHNcclxuICAgKi9cclxuICBnZXRBc3Nlc3NtZW50TG9ja01lc3NhZ2UoKTogc3RyaW5nIHtcclxuICAgIGlmICghdGhpcy5jb250ZW50IHx8ICF0aGlzLmhpZXJhcmNoeU1hcERhdGEpIHtcclxuICAgICAgcmV0dXJuICcnXHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgaGFzaERhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbdGhpcy5jb250ZW50LmlkZW50aWZpZXJdXHJcbiAgICBcclxuICAgIC8vIENoZWNrIGlmIGhhc2htYXAgaGFzIHByZS1jb21wdXRlZCBhc3Nlc3NtZW50IGxvY2sgbWVzc2FnZVxyXG4gICAgaWYgKGhhc2hEYXRhICYmIGhhc2hEYXRhLmFzc2Vzc21lbnRMb2NrTWVzc2FnZSkge1xyXG4gICAgICByZXR1cm4gaGFzaERhdGEuYXNzZXNzbWVudExvY2tNZXNzYWdlXHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuaXNNaWxlc3RvbmVBc3Nlc3NtZW50TG9ja2VkKSB7XHJcbiAgICAgIHJldHVybiAnVGhpcyBjb250ZW50IGlzIGxvY2tlZC4gQ29tcGxldGUgYWxsIG1hbmRhdG9yeSBpdGVtcyB0byB1bmxvY2sgdGhlIGFzc2Vzc21lbnQuJ1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiAnJ1xyXG4gIH1cclxuXHJcbiAgc2hvdWxkU2hvd0Rvd25sb2FkQnV0dG9uKGNvbnRlbnQ6IE5zQ29udGVudC5JQ29udGVudCB8IG51bGwpOiBib29sZWFuIHtcclxuICAgIGlmICghY29udGVudCkge1xyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuXHJcbiAgICAvLyBDaGVjayBpZiBjb250ZW50IGhhcyBhbiBhcnRpZmFjdCBVUkwgKGRvd25sb2FkYWJsZSByZXNvdXJjZSlcclxuICAgIGlmICghY29udGVudC5hcnRpZmFjdFVybCkge1xyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuXHJcbiAgICAvLyBDaGVjayBpZiBiYXNlIGNvbnRlbnQgcmVzb3VyY2UgY2F0ZWdvcnkgaW5jbHVkZXMgXCJDYXNlIFN0dWR5XCJcclxuICAgIGlmICghdGhpcy5iYXNlQ29udGVudFJlYWREYXRhPy5jb3Vyc2VDYXRlZ29yeSB8fFxyXG4gICAgICB0aGlzLmJhc2VDb250ZW50UmVhZERhdGEuY291cnNlQ2F0ZWdvcnkgIT09IE5zQ29udGVudC5FQ291cnNlQ2F0ZWdvcnkuQ0FTRV9TVFVEWSkge1xyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuXHJcbiAgICAvL2ZvciBwdWJsaWMgc2NlbmFyaW8gY2hlY2sgaWYgaXRzIHBsYXllciBwbGFnZSB0aGVuIG9ubHkgZW5hYmxlIGRvd25sb2FkXHJcbiAgICBpZiAodGhpcy5mb3JQcmV2aWV3ICYmICF3aW5kb3cubG9jYXRpb24uaHJlZi5pbmNsdWRlcygnL3ZpZXdlci8nKSkge1xyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuXHJcbiAgICAvLyBmb3IgbG9nZ2VkIGluIHVzZXIgY2hlY2sgaWYgdXNlciBlbnJvbGxlZCB0aGVuIG9ubHkgYWxsb3cgZG93bmxvYWRcclxuICAgIGlmICghdGhpcy5mb3JQcmV2aWV3ICYmICF0aGlzLmlzRW5yb2xsZWQpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlXHJcbiAgICB9XHJcblxyXG4gICAgLy8gRGVmaW5lIGRvd25sb2FkYWJsZSBNSU1FIHR5cGVzXHJcbiAgICBjb25zdCBkb3dubG9hZGFibGVNaW1lVHlwZXMgPSBbXHJcbiAgICAgIE5zQ29udGVudC5FTWltZVR5cGVzLlBERlxyXG4gICAgXVxyXG5cclxuICAgIHJldHVybiBkb3dubG9hZGFibGVNaW1lVHlwZXMuaW5jbHVkZXMoY29udGVudC5taW1lVHlwZSlcclxuICB9XHJcblxyXG4gIGRvd25sb2FkQ29udGVudChjb250ZW50OiBOc0NvbnRlbnQuSUNvbnRlbnQsIGV2ZW50PzogTW91c2VFdmVudCkge1xyXG4gICAgaWYgKGV2ZW50KSB7XHJcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KClcclxuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcclxuICAgIH1cclxuICAgIGNvbnN0IHBhZ2VJZCA9IGBhcHAvdG9jL3BhZ2VJZC8ke2NvbnRlbnQuaWRlbnRpZmllcn1gXHJcbiAgICB0aGlzLnJlc291cmNlRG93bmxvYWRIZWxwZXJTdmMuZG93bmxvYWRQREYoY29udGVudCwgcGFnZUlkKVxyXG4gICAgY29uc29sZS5sb2coJ2NvbnRlbnQnLCBjb250ZW50KVxyXG4gICAgY29uc29sZS5sb2coJ2Jhc2VDb250ZW50JywgdGhpcy5iYXNlQ29udGVudFJlYWREYXRhKVxyXG4gIH1cclxuXHJcblxyXG5cclxuICAvKipcclxuICAgKiBWaWV3IG1pbGVzdG9uZSBhY2hpZXZlbWVudCAtIGNhbGxzIHRoZSBhY2hpZXZlbWVudCBBUEkgYW5kIHNob3dzIHRoZSByZXN1bHRcclxuICAgKi9cclxuICB2aWV3TWlsZXN0b25lQWNoaWV2ZW1lbnQoZXZlbnQ/OiBNb3VzZUV2ZW50KSB7XHJcbiAgICBpZiAoZXZlbnQpIHtcclxuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKVxyXG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKVxyXG4gICAgfVxyXG5cclxuICAgIGlmICghdGhpcy5jb250ZW50IHx8ICF0aGlzLmJhdGNoSWQgfHwgdGhpcy5hY2hpZXZlbWVudExvYWRpbmcpIHtcclxuICAgICAgcmV0dXJuXHJcbiAgICB9XHJcblxyXG4gICAgLy8gR2V0IHVzZXIgSUQgZnJvbSBDb25maWd1cmF0aW9uc1NlcnZpY2VcclxuICAgIGNvbnN0IHVzZXJJZCA9IHRoaXMuY29uZmlnU3ZjPy51c2VyUHJvZmlsZT8udXNlcklkXHJcbiAgICBpZiAoIXVzZXJJZCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdVc2VyIElEIG5vdCBmb3VuZCcpXHJcbiAgICAgIHJldHVyblxyXG4gICAgfVxyXG5cclxuICAgIC8vIEV4dHJhY3QgbWlsZXN0b25lIElEIChlLmcuLCBcIm0xXCIsIFwibTJcIikgZnJvbSB0aGUgY29udGVudCBuYW1lIG9yIGluZGV4XHJcbiAgICAvLyBUcnkgdG8gZ2V0IG1pbGVzdG9uZSBudW1iZXIgZnJvbSB0aGUgaW5kZXggb3IgZXh0cmFjdCBmcm9tIGNvbnRlbnRcclxuICAgIGxldCBtaWxlc3RvbmVJZCA9ICdtJyArICh0aGlzLmluZGV4IC0gMSkgLy8gaW5kZXggaXMgdHlwaWNhbGx5IDEtYmFzZWQsIG1pbGVzdG9uZXMgYXJlIDAtYmFzZWRcclxuXHJcbiAgICAvLyBJZiBjb250ZW50IG5hbWUgY29udGFpbnMgbWlsZXN0b25lIG51bWJlciwgZXh0cmFjdCBpdFxyXG4gICAgaWYgKHRoaXMuY29udGVudC5uYW1lKSB7XHJcbiAgICAgIGNvbnN0IG1hdGNoID0gdGhpcy5jb250ZW50Lm5hbWUubWF0Y2goL21pbGVzdG9uZVxccyooXFxkKykvaSlcclxuICAgICAgaWYgKG1hdGNoKSB7XHJcbiAgICAgICAgbWlsZXN0b25lSWQgPSAnbScgKyBtYXRjaFsxXVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgY291cnNlSWQgPSB0aGlzLmJhc2VDb250ZW50UmVhZERhdGE/LmlkZW50aWZpZXIgfHwgdGhpcy5yb290SWRcclxuXHJcbiAgICB0aGlzLmFjaGlldmVtZW50TG9hZGluZyA9IHRydWVcclxuXHJcbiAgICB0aGlzLmFwcFRvY1N2Yy5nZW5lcmF0ZU1pbGVzdG9uZUFjaGlldmVtZW50KHVzZXJJZCwgY291cnNlSWQsIHRoaXMuYmF0Y2hJZCwgbWlsZXN0b25lSWQpLnN1YnNjcmliZSh7XHJcbiAgICAgIG5leHQ6IChyZXNwb25zZTogYW55KSA9PiB7XHJcbiAgICAgICAgdGhpcy5hY2hpZXZlbWVudExvYWRpbmcgPSBmYWxzZVxyXG4gICAgICAgIGNvbnNvbGUubG9nKCdBY2hpZXZlbWVudCBnZW5lcmF0ZWQgc3VjY2Vzc2Z1bGx5OicsIHJlc3BvbnNlKVxyXG4gICAgICAgIC8vIFNob3cgYWNoaWV2ZW1lbnQgZGlhbG9nIG9yIGhhbmRsZSByZXNwb25zZVxyXG4gICAgICAgIGlmIChyZXNwb25zZSAmJiByZXNwb25zZS5yZXN1bHQpIHtcclxuICAgICAgICAgIC8vIE9wZW4gYSBkaWFsb2cgdG8gc2hvdyB0aGUgYWNoaWV2ZW1lbnRcclxuICAgICAgICAgIHRoaXMuZGlhbG9nLm9wZW4oQ2VydGlmaWNhdGVEaWFsb2dDb21wb25lbnQsIHtcclxuICAgICAgICAgICAgd2lkdGg6ICcxMzAwcHgnLFxyXG4gICAgICAgICAgICBkYXRhOiB7XHJcbiAgICAgICAgICAgICAgY2V0OiByZXNwb25zZS5yZXN1bHQucHJpbnRVcmkgfHwgcmVzcG9uc2UucmVzdWx0LnN2Z0RhdGEsXHJcbiAgICAgICAgICAgICAgY2VydElkOiByZXNwb25zZS5yZXN1bHQuaWRlbnRpZmllcixcclxuICAgICAgICAgICAgICBpc0FjaGlldmVtZW50OiB0cnVlXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICB9KVxyXG4gICAgICAgIH1cclxuICAgICAgfSxcclxuICAgICAgZXJyb3I6IChlcnJvcjogYW55KSA9PiB7XHJcbiAgICAgICAgdGhpcy5hY2hpZXZlbWVudExvYWRpbmcgPSBmYWxzZVxyXG4gICAgICAgIC8vIFNob3cgZXJyb3IgbWVzc2FnZSBpbiBzbmFja2JhclxyXG4gICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGVycm9yPy5lcnJvcj8ucmVzdWx0Py5tZXNzYWdlIHx8IGVycm9yPy5tZXNzYWdlIHx8ICdGYWlsZWQgdG8gZ2VuZXJhdGUgYWNoaWV2ZW1lbnQnXHJcbiAgICAgICAgdGhpcy5zbmFja0Jhci5vcGVuKGVycm9yTWVzc2FnZSwgJ0Nsb3NlJywge1xyXG4gICAgICAgICAgZHVyYXRpb246IDUwMDAsXHJcbiAgICAgICAgICBob3Jpem9udGFsUG9zaXRpb246ICdjZW50ZXInLFxyXG4gICAgICAgICAgdmVydGljYWxQb3NpdGlvbjogJ2JvdHRvbScsXHJcbiAgICAgICAgICBwYW5lbENsYXNzOiBbJ2Vycm9yLXNuYWNrYmFyJ11cclxuICAgICAgICB9KVxyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGdlbmVyYXRpbmcgYWNoaWV2ZW1lbnQ6JywgZXJyb3IpXHJcbiAgICAgIH1cclxuICAgIH0pXHJcbiAgfVxyXG5cclxufVxyXG4iLCI8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudCAmJiAhaXNQcmVBc3Nlc3NtZW50XCI+XHJcbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNDb2xsZWN0aW9uICYmICFpc01vZHVsZVwiPlxyXG4gICAgICAgIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwiY29sbGVjdGlvblRlbXBsYXRlXCI+XHJcbiAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc0NvbGxlY3Rpb24gJiYgaXNNb2R1bGVcIj5cclxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudD8ubW9kdWxlUmVzb3Vyc2VDb3VudFwiPlxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNvbGxlY3Rpb25UZW1wbGF0ZVwiPlxyXG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgIDwvbmctY29udGFpbmVyPlxyXG5cclxuICAgIDxkaXYgKm5nSWY9XCJpc1Jlc291cmNlXCIgY2xhc3M9XCJyZXNvdXJjZS1jb250YWluZXJcIlxyXG4gICAgICAgIFtuZ0NsYXNzXT1cInBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKSAmJiBpc0Vucm9sbGVkID8gJ2NvbnRlbnQtYWN0aXZlLXJlc291cmNlJzogJ2NvbnRlbnQtbm90LWFjdGl2ZS1yZXNvdXJjZSdcIj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwicmVzb3VyY2UgZmxleCAgc206ZmxleC1yb3cgZmxleC1zdGFydCB3aWR0aC1leHBhbmQgdy0xMDAgc206cHItNCBzbTp3LWF1dG9cIlxyXG4gICAgICAgICAgICBbbmdDbGFzc109XCJ7J2FjdGl2ZVJlc291cmNlJzogcGF0aFNldD8uaGFzKGNvbnRlbnQ/LmlkZW50aWZpZXIpICYmIGlzRW5yb2xsZWR9XCI+XHJcbiAgICAgICAgICAgIDwhLS0gTG9jayBtZXNzYWdlIGZvciBjdXJhdGVkIHByb2dyYW1zIG9ubHkgKHNob3duIGFib3ZlIGNvbnRlbnQpIC0tPlxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudD8ucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCAmJiBjaGVja0ZvckN1cmF0ZWRQcm9ncmFtICYmXHJcbiAgICAgICAgICAgICFpc0NvbnRlbnRVbmxvY2tlZFwiPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbnRlbnQtbG9ja2luZyBmbGV4IHctZnVsbCBmbGV4LW1pZGRsZSBtYi0yIGdhcC0zXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwibG9jay1pY29uXCI+bG9jazwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJsb2NrLW1lc3NhZ2UgbWF0LWJvZHktMlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBUaGUgY29udGVudCBpcyBsb2NrZWQuIENvbXBsZXRlIHByb2dyYW0gb3IgYWxsIGNvdXJzZXMgdG8gdmlldyB0aGlzIG1vZHVsZVxyXG4gICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnQ/LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgJiYgY2hlY2tGb3JDdXJhdGVkUHJvZ3JhbSAmJlxyXG4gICAgICAgICAgICBpc0NvbnRlbnRVbmxvY2tlZFwiPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbnRlbnQtbG9ja2luZyBmbGV4IHctZnVsbCBmbGV4LW1pZGRsZSBtYi0yIGdhcC0zXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwidW5sb2NrLWljb25cIj5sb2NrX29wZW5fcmlnaHQ8L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidW5sb2NrLW1lc3NhZ2UgbWF0LWJvZHktMlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBUaGlzIGNvbnRlbnQgaXMgdW5sb2NrZWQuXHJcbiAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXdyYXAgaXRlbXMtc3RhcnQganVzdGlmeS1zdGFydCBzbTpqdXN0aWZ5LWVuZFwiPlxyXG4gICAgICAgICAgICAgICAgPCEtLSA8YnV0dG9uICpuZ0lmPVwiIWZvclByZXZpZXcgJiYgY29udGVudD8uYXJ0aWZhY3RVcmwgJiYgIWlzWFNtYWxsICYmIGlzQWxsb3dlZCAmJiBpc0VuYWJsZWRcIiB0eXBlPVwiYnV0dG9uXCJcclxuICAgICAgICAgICAgICAgICAgICBtYXQtaWNvbi1idXR0b24gY2xhc3M9XCJcIiBbbWF0TWVudVRyaWdnZXJGb3JdPVwiYnV0dG9uTWVudVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5tb3JlX3ZlcnRpY2FsPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPiAtLT5cclxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc0Vucm9sbGVkICAmJiAhaXNNaWxlc3RvbmVMb2NrZWQgJiYgIWlzUGFyZW50TWlsZXN0b25lTG9ja2VkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxyXG4gICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIiFmb3JQcmV2aWV3ICYmICBjb250ZW50Py5pZGVudGlmaWVyICYmIGdldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpIDsgZWxzZSBlbHNlQmxvY2tcIj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRDb21wbGV0aW9uU3RhdHVzKGNvbnRlbnQ/LmlkZW50aWZpZXIpID09IDJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb21wbGV0ZWRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJjb21wbGV0ZWQtaWNvblwiIFtjb2xvcl09XCJibHVlXCI+Y2hlY2tfY2lyY2xlPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldENvbXBsZXRpb25TdGF0dXMoY29udGVudD8uaWRlbnRpZmllcikgPCAyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlLXByb2dyZXNzIGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgcHJvZ3Jlc3NcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwZXJjZW50XT1cImdldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpXCIgW3JhZGl1c109XCIxMFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlV2lkdGhdPVwiMlwiIFtpbm5lclN0cm9rZVdpZHRoXT1cIjJcIiBbc3BhY2VdPVwiLTJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZUNvbG9yXT1cInByb2dyZXNzQ29sb3IyKClcIiBbaW5uZXJTdHJva2VDb2xvcl09XCIncmdiYSgwLCAwLCAwLCAwLjE2KSdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthbmltYXRpb25dPVwidHJ1ZVwiIFthbmltYXRpb25EdXJhdGlvbl09XCIyNTBcIiBbc2hvd1RpdGxlXT1cImZhbHNlXCIgW3Nob3dVbml0c109XCJmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dTdWJ0aXRsZV09XCJmYWxzZVwiIFtzaG93SW5uZXJTdHJva2VdPVwidHJ1ZVwiIFtjbG9ja3dpc2VdPVwidHJ1ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2JhY2tncm91bmRPcGFjaXR5XT1cIjBcIiBbYmFja2dyb3VuZEdyYWRpZW50XT1cImZhbHNlXCIgW2JhY2tncm91bmRTdHJva2VXaWR0aF09XCIzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRUb29sdGlwPVwiSW4gcHJvZ3Jlc3NcIiBbc2hvd1plcm9PdXRlclN0cm9rZV09ZmFsc2UgW2JhY2tncm91bmRQYWRkaW5nXT1cIi05XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3RhcnRGcm9tWmVyb109XCJmYWxzZVwiIFtiYWNrZ3JvdW5kUGFkZGluZ109XCIwXCIgW2ltYWdlSGVpZ2h0XT1cIjIyXCIgW2ltYWdlV2lkdGhdPVwiMjJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93QmFja2dyb3VuZF09XCJmYWxzZVwiIFtvdXRlclN0cm9rZUxpbmVjYXBdPVwiJ2J1dHQnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2NpcmNsZS1wcm9ncmVzcz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPHdzLXdpZGdldC1jb250ZW50LXByb2dyZXNzICpuZ0lmPVwiY29udGVudD8uaWRlbnRpZmllclwiIFtmb3JQcmV2aWV3XT1cImZvclByZXZpZXdcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtjb250ZW50SWRdPVwiY29udGVudD8uaWRlbnRpZmllclwiIGNsYXNzPVwicHJvZ3Jlc3MtYmFyLXRoaW5cIiBbcHJvZ3Jlc3NdPVwiY29udGVudD8uY29tcGxldGlvblBlcmNlbnRhZ2VcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtwcm9ncmVzc1R5cGVdPVwiJ3BlcmNlbnRhZ2UnXCI+XHJcbiAgICAgICAgICAgICAgICAgIDwvd3Mtd2lkZ2V0LWNvbnRlbnQtcHJvZ3Jlc3M+IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI2Vsc2VCbG9jaz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZS1wcm9ncmVzcyBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHByb2dyZXNzXCIgW3BlcmNlbnRdPVwiMFwiIFtyYWRpdXNdPVwiMTFcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlV2lkdGhdPVwiMlwiIFtpbm5lclN0cm9rZVdpZHRoXT1cIjJcIiBbb3V0ZXJTdHJva2VDb2xvcl09XCInIzgwODA4MCdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lubmVyU3Ryb2tlQ29sb3JdPVwiJyM4MDgwODAnXCIgW2FuaW1hdGlvbl09XCJ0cnVlXCIgW3NwYWNlXT1cIi0yXCIgW3Nob3dVbml0c109XCJmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYW5pbWF0aW9uRHVyYXRpb25dPVwiMjUwXCIgW3Nob3dUaXRsZV09XCJmYWxzZVwiIFtiYWNrZ3JvdW5kUGFkZGluZ109XCIwXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtiYWNrZ3JvdW5kUGFkZGluZ109XCItOVwiIFtvdXRlclN0cm9rZUxpbmVjYXBdPVwiJ2J1dHQnXCIgbWF0VG9vbHRpcD1cIk5vdCBzdGFydGVkXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93U3VidGl0bGVdPVwiZmFsc2VcIiBbc2hvd0lubmVyU3Ryb2tlXT1cInRydWVcIiBbY2xvY2t3aXNlXT1cInRydWVcIiBbaW1hZ2VIZWlnaHRdPVwiMjJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2ltYWdlV2lkdGhdPVwiMjJcIiBbc2hvd0JhY2tncm91bmRdPVwiZmFsc2VcIj48L2NpcmNsZS1wcm9ncmVzcz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSA8cD5ubyBkYXRhPC9wPiAtLT5cclxuICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8IS0tIGRlYWN0aXZhdGVkIGFzIHBlciBOSUMgQ0VPIHJlcXVpcmVtZW50IHRvIGFjY2VzcyBjb3Vyc2Ugd3Rob3V0IGxvZ2luIC0tPlxyXG4gICAgICAgICAgICA8IS0tIEZvciBsb2NrZWQgYXNzZXNzbWVudHM6IHNob3cgY29udGVudCBidXQgbWFrZSBpdCBub24tY2xpY2thYmxlIC0tPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwid2lkdGgtZXhwYW5kXCIgKm5nSWY9XCJpc01pbGVzdG9uZUFzc2Vzc21lbnRMb2NrZWQgJiYgaXNFbnJvbGxlZDsgZWxzZSBjbGlja2FibGVDb250ZW50XCJcclxuICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnbWwtMyc6IGlzRW5yb2xsZWR9XCI+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC10cnVuY2F0ZSBvcGFjaXR5LTYwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2wgc206ZmxleC1yb3cgZmxleC13cmFwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBnYXAtMiB3LWZ1bGxcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cInRleHQtZ3JheS01MDBcIj5sb2NrPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwibWFyZ2luLXJlbW92ZSB0ZXh0LXRydW5jYXRlIG1hdC1ib2R5LTIgZmxleC1hdXRvIGZvbnQtYm9sZCBub2R0cmFuc2xhdGUgdGV4dC1ncmF5LTYwMFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGNvbnRlbnQ/Lm5hbWUgfCB0cnVuY2F0ZTo1MCB9fVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9wPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjb250ZW50LXR5cGUgb3B0aW9uYWwtc3BhbiBub2R0cmFuc2xhdGVcIiAqbmdJZj1cImNvbnRlbnQ/Lm9wdGlvbmFsUmVhZGluZ1wiPnt7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAncGxheWVyYnJpZWYub3B0aW9uYWwnIHwgdHJhbnNsYXRlIHwgdGl0bGVjYXNlfX0gPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gZm9yIGRlZmF1bHQgZ3JleSBpY29ucyAtLT5cclxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIXBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKSB8fCAhaXNFbnJvbGxlZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVzaWNvbnMgd3MtbWF0LWJsYWNrNjAtdGV4dFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS92aWRlby5zdmdcIiBhbHQ9XCJWaWRlb1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICd2aWRlby9tcDQnIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAndmlkZW8veC15b3V0dWJlJyB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgY29udGVudD8ubWltZVR5cGUgPT09J2FwcGxpY2F0aW9uL3gtbXBlZ1VSTCdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvYXVkaW8uc3ZnXCIgYWx0PVwiQXVkaW9cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIiAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXVkaW8vbXBlZydcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvcGRmLnN2Z1wiIGFsdD1cIlBERlwiIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9wZGYnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2xpbmsuc3ZnXCIgYWx0PVwiSW50ZXJhY3RpdmVDb250ZW50XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLmVrc3RlcC5odG1sLWFyY2hpdmUnIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAndGV4dC94LXVybCdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvYXNzZXNzbWVudC5zdmdcIiBhbHQ9XCJBc3Nlc3NtZW50XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vanNvbicgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9xdWl6JyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5zdW5iaXJkLnF1ZXN0aW9uc2V0J1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9pbWFnZS5zdmdcIiBhbHQ9XCJJbWFnZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2ltYWdlL3BuZycgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICdpbWFnZS9qcGVnJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9jb250ZW50X2NvcHkuc3ZnXCIgY2xhc3M9XCJjb250ZW50aWNvblwiIGFsdD1cIkNvdXJzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLmVrc3RlcC5jb250ZW50LWNvbGxlY3Rpb24nIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vc3VydmV5J1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9tb2R1bGUuc3ZnXCIgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWx0PVwib2ZmbGluZSBzZXNzaW9uc1wiICpuZ0lmPVwiY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL29mZmxpbmUnXCI+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5DT01QX0FTU0VTU01FTlQgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuU1RBTkRBTE9ORV9BU1NFU1NNRU5UIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJyZXNvdXJjZUR1cmF0aW9uIHdzLW1hdC1ibGFjazYwLXRleHQgbm9kdHJhbnNsYXRlXCI+e3sgY29udGVudD8ubWF4UXVlc3Rpb25zXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH19IHt7ICdwbGF5ZXJicmllZi5xdWVzdGlvbnMnIHwgdHJhbnNsYXRlIHwgdGl0bGVjYXNlfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhKGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5DT01QX0FTU0VTU01FTlQgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuU1RBTkRBTE9ORV9BU1NFU1NNRU5UIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicmVzb3VyY2VEdXJhdGlvbiB3cy1tYXQtYmxhY2s2MC10ZXh0IG5vZHRyYW5zbGF0ZVwiPnt7IChjb250ZW50Py5kdXJhdGlvbnx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZXJhcmNoeU1hcERhdGFbY29udGVudD8uaWRlbnRpZmllcl0/LmV4cGVjdGVkRHVyYXRpb24gfHwgMCl8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpcGVEdXJhdGlvblRyYW5zZm9ybTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2htcydcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgPCEtLSBMb2NrIG1lc3NhZ2UgZGlzcGxheWVkIEJFTE9XIGFzc2Vzc21lbnQgZGV0YWlscyB3aGVuIGxvY2tlZCAtLT5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb250ZW50LWxvY2tpbmcgZmxleCB3LWZ1bGwgZmxleC1taWRkbGUgbXQtMiBnYXAtMiBweC0yIHB5LTEgYmctb3JhbmdlLTUwIGJvcmRlci1sLTQgYm9yZGVyLW9yYW5nZS00MDBcIj5cclxuICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJsb2NrLWljb24gdGV4dC1vcmFuZ2UtNjAwXCIgc3R5bGU9XCJmb250LXNpemU6IDE4cHg7IHdpZHRoOiAxOHB4OyBoZWlnaHQ6IDE4cHg7XCI+bG9jazwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJsb2NrLW1lc3NhZ2UgbWF0LWJvZHktMiB0ZXh0LW9yYW5nZS04MDBcIiBzdHlsZT1cImZvbnQtc2l6ZTogMTNweDtcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgVGhpcyBjb250ZW50IGlzIGxvY2tlZC4gQ29tcGxldGUgYWxsIG1hbmRhdG9yeSBpdGVtcyB0byB1bmxvY2sgdGhlIGFzc2Vzc21lbnQuXHJcbiAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgPCEtLSBDbGlja2FibGUgY29udGVudCB0ZW1wbGF0ZSAod2hlbiBOT1QgbG9ja2VkKSAtLT5cclxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNjbGlja2FibGVDb250ZW50PlxyXG4gICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJ3aWR0aC1leHBhbmRcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtjbGFzcy5kaXNhYmxlZF09XCIoZm9yUHJldmlldyB8fCAhaXNFbmFibGVkIHx8ICFpc0Vucm9sbGVkIHx8ICFpc0JhdGNoSW5Qcm9nZXNzIHx8ICFpc0NvbnRlbnRVbmxvY2tlZCB8fCBpc1BhcmVudE1pbGVzdG9uZUxvY2tlZCkgPyB0cnVlIDogbnVsbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydtbC0zJzogaXNFbnJvbGxlZH1cIlxyXG4gICAgICAgICAgICAgICAgICAgIFtyb3V0ZXJMaW5rXT1cIihpc0FsbG93ZWQgJiYgIWZvclByZXZpZXcgJiYgaXNFbmFibGVkICYmICFpc1BhcmVudE1pbGVzdG9uZUxvY2tlZCkgPyByZXNvdXJjZUxpbmsudXJsIDogbnVsbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgW3F1ZXJ5UGFyYW1zXT1cIihpc0FsbG93ZWQgJiYgIWZvclByZXZpZXcgJiYgaXNFbmFibGVkICYmICFpc1BhcmVudE1pbGVzdG9uZUxvY2tlZCkgID8gcmVzb3VyY2VMaW5rLnF1ZXJ5UGFyYW1zIDogbnVsbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgW21hdFRvb2x0aXBdPVwiaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQgPyAnVGhpcyBjb250ZW50IGlzIGxvY2tlZC4gQ29tcGxldGUgcHJldmlvdXMgbWlsZXN0b25lIHRvIHZpZXcgdGhpcyBjb250ZW50LicgOiAnJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcFBvc2l0aW9uPVwiYWJvdmVcIj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IFtuZ0NsYXNzXT1cInsncmVzb3VyY2UtYWN0aXZlJzogcGF0aFNldD8uaGFzKGNvbnRlbnQ/LmlkZW50aWZpZXIpICYmIGlzRW5yb2xsZWR9XCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtdHJ1bmNhdGUgXCIgW25nQ2xhc3NdPVwieydjdXJzb3ItcG9pbnRlcic6ICFpc0VuYWJsZWQgJiYgaXNFbnJvbGxlZH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiY29udGVudC52aWV3Q2hpbGRyZW4gPSAhY29udGVudC52aWV3Q2hpbGRyZW47IHJhaXNlVGVsZW1ldHJ5KCk7IGNoYW5nZVJlc291cmNlKClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2wgc206ZmxleC1yb3cgZmxleC13cmFwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cIm1hcmdpbi1yZW1vdmUgdGV4dC10cnVuY2F0ZSBtYXQtYm9keS0yIGZsZXgtYXV0byBmb250LWJvbGQgbm9kdHJhbnNsYXRlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J3RleHQtYWN0aXZlJzogcGF0aFNldD8uaGFzKGNvbnRlbnQ/LmlkZW50aWZpZXIpICYmIGlzRW5yb2xsZWR9XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgY29udGVudD8ubmFtZSB8IHRydW5jYXRlOjUwIH19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3A+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNvbnRlbnQtdHlwZSBvcHRpb25hbC1zcGFuIG5vZHRyYW5zbGF0ZVwiICpuZ0lmPVwiY29udGVudD8ub3B0aW9uYWxSZWFkaW5nXCI+e3tcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAncGxheWVyYnJpZWYub3B0aW9uYWwnIHwgdHJhbnNsYXRlIHwgdGl0bGVjYXNlfX0gPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBmb3IgZGVmYXVsdCBncmV5IGljb25zIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIXBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKSB8fCAhaXNFbnJvbGxlZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlc2ljb25zIHdzLW1hdC1ibGFjazYwLXRleHRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L3ZpZGVvLnN2Z1wiIGFsdD1cIlZpZGVvXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICd2aWRlby9tcDQnIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAndmlkZW8veC15b3V0dWJlJyB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ/Lm1pbWVUeXBlID09PSdhcHBsaWNhdGlvbi94LW1wZWdVUkwnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9hdWRpby5zdmdcIiBhbHQ9XCJBdWRpb1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIiAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXVkaW8vbXBlZydcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L3BkZi5zdmdcIiBhbHQ9XCJQREZcIiBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3BkZidcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2xpbmsuc3ZnXCIgYWx0PVwiSW50ZXJhY3RpdmVDb250ZW50XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi92bmQuZWtzdGVwLmh0bWwtYXJjaGl2ZScgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICd0ZXh0L3gtdXJsJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvYXNzZXNzbWVudC5zdmdcIiBhbHQ9XCJBc3Nlc3NtZW50XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9qc29uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3F1aXonIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLnN1bmJpcmQucXVlc3Rpb25zZXQnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9pbWFnZS5zdmdcIiBhbHQ9XCJJbWFnZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnaW1hZ2UvcG5nJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2ltYWdlL2pwZWcnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9jb250ZW50X2NvcHkuc3ZnXCIgY2xhc3M9XCJjb250ZW50aWNvblwiIGFsdD1cIkNvdXJzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5la3N0ZXAuY29udGVudC1jb2xsZWN0aW9uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3N1cnZleSdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L21vZHVsZS5zdmdcIiBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWx0PVwib2ZmbGluZSBzZXNzaW9uc1wiICpuZ0lmPVwiY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL29mZmxpbmUnXCI+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkNPTVBfQVNTRVNTTUVOVCB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuU1RBTkRBTE9ORV9BU1NFU1NNRU5UIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5QUkFDVElDRV9SRVNPVVJDRVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInJlc291cmNlRHVyYXRpb24gd3MtbWF0LWJsYWNrNjAtdGV4dCBub2R0cmFuc2xhdGVcIj57eyBjb250ZW50Py5tYXhRdWVzdGlvbnNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH19IHt7ICdwbGF5ZXJicmllZi5xdWVzdGlvbnMnIHwgdHJhbnNsYXRlIHwgdGl0bGVjYXNlfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiEoY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5GSU5BTF9BU1NFU1NNRU5UIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5DT01QX0FTU0VTU01FTlQgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlNUQU5EQUxPTkVfQVNTRVNTTUVOVCB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuUFJBQ1RJQ0VfUkVTT1VSQ0UpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicmVzb3VyY2VEdXJhdGlvbiB3cy1tYXQtYmxhY2s2MC10ZXh0IG5vZHRyYW5zbGF0ZVwiPnt7IChjb250ZW50Py5kdXJhdGlvbnx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWVyYXJjaHlNYXBEYXRhW2NvbnRlbnQ/LmlkZW50aWZpZXJdPy5leHBlY3RlZER1cmF0aW9uIHx8IDApfFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGlwZUR1cmF0aW9uVHJhbnNmb3JtOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2htcydcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH19PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8IS0tIGZvciB3aGl0ZSBpY29ucyB3aGVuIGNvbnRlbnQgaGlnaGxpZ2h0ZWQgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKSAmJiBpc0Vucm9sbGVkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZXNpY29ucyB3cy1tYXQtd2hpdGUtdGV4dFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvd2hpdGUvdmlkZW8uc3ZnXCIgYWx0PVwiVmlkZW9cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIiAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAndmlkZW8vbXA0JyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ3ZpZGVvL3gteW91dHViZScgfHxcclxuICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ/Lm1pbWVUeXBlID09PSdhcHBsaWNhdGlvbi94LW1wZWdVUkwnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9hdWRpby5zdmdcIiBhbHQ9XCJBdWRpb1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhdWRpby9tcGVnJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvd2hpdGUvcGRmLnN2Z1wiIGFsdD1cIlBERlwiIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9wZGYnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9saW5rLnN2Z1wiIGFsdD1cIkludGVyYWN0aXZlQ29udGVudFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5la3N0ZXAuaHRtbC1hcmNoaXZlJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ3RleHQveC11cmwnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9hc3Nlc3NtZW50LnN2Z1wiIGFsdD1cIkFzc2Vzc21lbnRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9qc29uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3F1aXonIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLnN1bmJpcmQucXVlc3Rpb25zZXQnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2ltYWdlLnN2Z1wiIGFsdD1cIkltYWdlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnaW1hZ2UvcG5nJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2ltYWdlL2pwZWcnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9jb250ZW50X2NvcHkuc3ZnXCIgY2xhc3M9XCJjb250ZW50aWNvblwiIGFsdD1cIkNvdXJzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLmVrc3RlcC5jb250ZW50LWNvbGxlY3Rpb24nIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vc3VydmV5J1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvd2hpdGUvbW9kdWxlLnN2Z1wiIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsdD1cIm9mZmxpbmUgc2Vzc2lvbnNcIiAqbmdJZj1cImNvbnRlbnQubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9vZmZsaW5lJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5DT01QX0FTU0VTU01FTlQgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuU1RBTkRBTE9ORV9BU1NFU1NNRU5UIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJyZXNvdXJjZUR1cmF0aW9uIHdzLW1hdC1ibGFjazYwLXRleHQgbm9kdHJhbnNsYXRlXCI+e3sgY29udGVudD8ubWF4UXVlc3Rpb25zXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH19IHt7ICdwbGF5ZXJicmllZi5xdWVzdGlvbnMnIHwgdHJhbnNsYXRlIHwgdGl0bGVjYXNlfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhKGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5DT01QX0FTU0VTU01FTlQgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuU1RBTkRBTE9ORV9BU1NFU1NNRU5UIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicmVzb3VyY2VEdXJhdGlvbiB3cy1tYXQtYmxhY2s2MC10ZXh0IG5vZHRyYW5zbGF0ZVwiPnt7IChjb250ZW50Py5kdXJhdGlvbnx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZXJhcmNoeU1hcERhdGFbY29udGVudD8uaWRlbnRpZmllcl0/LmV4cGVjdGVkRHVyYXRpb24gfHwgMCl8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpcGVEdXJhdGlvblRyYW5zZm9ybTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2htcydcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gRG93bmxvYWQgYnV0dG9uIGZvciBwZGYgcmVzb3VyY2VzIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzaG91bGRTaG93RG93bmxvYWRCdXR0b24oY29udGVudClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRvd25sb2FkLWJ0biBtYXQtYm9keS0yIG10LTIgc206bXQtMVwiIChjbGljayk9XCJkb3dubG9hZENvbnRlbnQoY29udGVudCwgJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J2FjdGl2ZSc6IHBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKX1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwiZG93bmxvYWQtbGluayBmbGV4IGl0ZW1zLWNlbnRlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiXCI+RG93bmxvYWQ8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2E+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvYT5cclxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG48L25nLWNvbnRhaW5lcj5cclxuXHJcbjxtYXQtbWVudSAjYnV0dG9uTWVudT1cIm1hdE1lbnVcIj5cclxuICAgIDxhIG1hdC1tZW51LWl0ZW0gW3JvdXRlckxpbmtdPVwiJy4uLycgKyBjb250ZW50Py5pZGVudGlmaWVyICsgJy9vdmVydmlldydcIiBbcXVlcnlQYXJhbXNdPVwiY29udGV4dFBhdGhcIlxyXG4gICAgICAgIGNsYXNzPVwiZmxleCBmbGV4LW1pZGRsZVwiPlxyXG4gICAgICAgIDxtYXQtaWNvbj50b2M8L21hdC1pY29uPlxyXG4gICAgICAgIDxoMyBjbGFzcz1cIm1hcmdpbi1yZW1vdmUgbm9kdHJhbnNsYXRlXCI+XHJcbiAgICAgICAgICAgIFZpZXcgRGV0YWlsc1xyXG4gICAgICAgIDwvaDM+XHJcbiAgICA8L2E+XHJcbjwvbWF0LW1lbnU+XHJcblxyXG48bmctdGVtcGxhdGUgI2NvbGxlY3Rpb25UZW1wbGF0ZT5cclxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc0NvbGxlY3Rpb25cIj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiY29sbGVjdGlvbi13cmFwcGVyIHAtNCBmbGV4IGZsZXgtY29sIHBvc2l0aW9uLXJlbGF0aXZlXCIgW25nQ2xhc3NdPVwieydvcGVuJzogY2hlY2soY29udGVudCksXHJcbiAgICAgICAgICAgICdjbG9zZSc6ICFjb250ZW50LnZpZXdDaGlsZHJlbixcclxuICAgICAgICAgICAgJ2NvdXJzZSc6IWlzTW9kdWxlLCAnbW9kdWxlJzogaXNNb2R1bGUsXHJcbiAgICAgICAgICAgICdjb250ZW50LWFjdGl2ZSc6IHBhdGhTZXQ/Lmhhcyhjb250ZW50LmlkZW50aWZpZXIpICYmIGlzRW5yb2xsZWR9XCI+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYXJkLWNvbGxlY3Rpb24gdy1hdXRvIHNtOnctMTAwIHBhZGRpbmctcmlnaHQteGxcIj5cclxuICAgICAgICAgICAgICAgIDwhLS0gPGltZyBjbGFzcz1cImNhcmQtdGh1bWJuYWlsIHdzLW1hdC1wcmltYXJ5LWxpdGUtYmFja2dyb3VuZFwiIFtzcmNdPVwiY29udGVudD8uYXBwSWNvblwiIGFsdD1cIlRodW1ibmFpbFwiXHJcbiAgICAgICAgICAgIChjbGljayk9XCJjb250ZW50LnZpZXdDaGlsZHJlbiA9ICFjb250ZW50LnZpZXdDaGlsZHJlblwiIFt3c1V0aWxzRGVmYXVsdFRodW1ibmFpbF09XCJkZWZhdWx0VGh1bWJuYWlsXCIgLz4gLS0+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCBmbGV4LXdyYXAgZmxleC1iZXR3ZWVuIHdpZHRoLWV4cGFuZCBwci0wIHctMTAwIFwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXRydW5jYXRlXCIgW25nQ2xhc3NdPVwieydjdXJzb3ItcG9pbnRlcic6ICFpc0VuYWJsZWR9XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNvbnRlbnQudmlld0NoaWxkcmVuID0gIWNvbnRlbnQudmlld0NoaWxkcmVuXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciBtYi0xIHNtOmZsZXgtcm93XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJpc01vZHVsZSAmJiBpc0Vucm9sbGVkICYmICFpc01pbGVzdG9uZUxvY2tlZCAmJiAhaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIWZvclByZXZpZXcgJiYgY29udGVudD8uaWRlbnRpZmllciAmJiBnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKSA7IGVsc2UgZWxzZUJsb2NrXCI+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0Q29tcGxldGlvblN0YXR1cyhjb250ZW50LmlkZW50aWZpZXIpID09IDJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb21wbGV0ZWQgbXItMlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cImNvbXBsZXRlZC1pY29uXCIgW2NvbG9yXT1cImJsdWVcIj5jaGVja19jaXJjbGU8L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0Q29tcGxldGlvblN0YXR1cyhjb250ZW50Py5pZGVudGlmaWVyKSA8IDJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxjaXJjbGUtcHJvZ3Jlc3MgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBwcm9ncmVzcyBtci0xXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGVyY2VudF09XCJnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKVwiIFtyYWRpdXNdPVwiMTBcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZVdpZHRoXT1cIjJcIiBbaW5uZXJTdHJva2VXaWR0aF09XCIyXCIgW3NwYWNlXT1cIi0yXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3V0ZXJTdHJva2VDb2xvcl09XCJwcm9ncmVzc0NvbG9yMigpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaW5uZXJTdHJva2VDb2xvcl09XCIncmdiYSgwLCAwLCAwLCAwLjE2KSdcIiBbYW5pbWF0aW9uXT1cInRydWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthbmltYXRpb25EdXJhdGlvbl09XCIyNTBcIiBbc2hvd1RpdGxlXT1cImZhbHNlXCIgW3Nob3dVbml0c109XCJmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dTdWJ0aXRsZV09XCJmYWxzZVwiIFtzaG93SW5uZXJTdHJva2VdPVwidHJ1ZVwiIFtjbG9ja3dpc2VdPVwidHJ1ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2JhY2tncm91bmRPcGFjaXR5XT1cIjBcIiBbYmFja2dyb3VuZEdyYWRpZW50XT1cImZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYmFja2dyb3VuZFN0cm9rZVdpZHRoXT1cIjNcIiBtYXRUb29sdGlwPVwiSW4gcHJvZ3Jlc3NcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93WmVyb091dGVyU3Ryb2tlXT1mYWxzZSBbYmFja2dyb3VuZFBhZGRpbmddPVwiLTdcIiBbc3RhcnRGcm9tWmVyb109XCJmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2JhY2tncm91bmRQYWRkaW5nXT1cIjBcIiBbaW1hZ2VIZWlnaHRdPVwiMThcIiBbaW1hZ2VXaWR0aF09XCIxOFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dCYWNrZ3JvdW5kXT1cImZhbHNlXCIgW291dGVyU3Ryb2tlTGluZWNhcF09XCInYnV0dCdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvY2lyY2xlLXByb2dyZXNzPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI2Vsc2VCbG9jaz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZS1wcm9ncmVzcyBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHByb2dyZXNzIG1yLTFcIiBbcGVyY2VudF09XCIwXCIgW3JhZGl1c109XCIxMVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3V0ZXJTdHJva2VXaWR0aF09XCIyXCIgW2lubmVyU3Ryb2tlV2lkdGhdPVwiMlwiIFtvdXRlclN0cm9rZUNvbG9yXT1cIicjODA4MDgwJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaW5uZXJTdHJva2VDb2xvcl09XCInIzgwODA4MCdcIiBbYW5pbWF0aW9uXT1cInRydWVcIiBbc3BhY2VdPVwiLTJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dVbml0c109XCJmYWxzZVwiIFthbmltYXRpb25EdXJhdGlvbl09XCIyNTBcIiBbc2hvd1RpdGxlXT1cImZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtiYWNrZ3JvdW5kUGFkZGluZ109XCIwXCIgW2JhY2tncm91bmRQYWRkaW5nXT1cIi05XCIgW291dGVyU3Ryb2tlTGluZWNhcF09XCInYnV0dCdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcD1cIk5vdCBzdGFydGVkXCIgW3Nob3dTdWJ0aXRsZV09XCJmYWxzZVwiIFtzaG93SW5uZXJTdHJva2VdPVwidHJ1ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xvY2t3aXNlXT1cInRydWVcIiBbaW1hZ2VIZWlnaHRdPVwiMjJcIiBbaW1hZ2VXaWR0aF09XCIyMlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2hvd0JhY2tncm91bmRdPVwiZmFsc2VcIj48L2NpcmNsZS1wcm9ncmVzcz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydjb2xsZWN0aW9uLWFjdGl2ZS1jbGFzcyc6IHBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKSAmJiBpc0Vucm9sbGVkfVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nICpuZ0lmPVwiaXNNaWxlc3RvbmVMb2NrZWRcIiBzcmM9XCJhc3NldHMvaWNvbnMvaHVicy9sb2NrLnN2Z1wiIGFsdD1cIkxvY2tlZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJsb2NrLWljb24gbXItMiBtYXJnaW4tYm90dG9tLXh4c1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJtYXJnaW4tcmVtb3ZlIHRleHQtdHJ1bmNhdGUgbWF0LXN1YmhlYWRpbmctMSBmbGV4LWF1dG8gZm9udC1ib2xkIG5vZHRyYW5zbGF0ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieyd0ZXh0LWFjdGl2ZSc6IHBhdGhTZXQ/Lmhhcyhjb250ZW50LmlkZW50aWZpZXIpICYmIGlzRW5yb2xsZWR9XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3tpc01pbGVzdG9uZSA/IGluZGV4IC0xIDogaW5kZXh9fS4gPC9zcGFuPnt7IGNvbnRlbnQ/Lm5hbWUgfCB0cnVuY2F0ZTo1MCB9fVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc01pbGVzdG9uZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cImlzTWlsZXN0b25lTG9ja2VkXCIgY2xhc3M9XCJsb2NrZWQtdGV4dCBtbC0yXCI+TG9ja2VkPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiY29udGVudD8uaXNNYW5kYXRvcnlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1hbmRhdG9yeS10ZXh0IG1hdC1jYXB0aW9uIG1sLTJcIj5NYW5kYXRvcnk8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3A+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0eXBlLWNvbnRhaW5lciByZXNvdXJjZSBtdC0yIHNtOm10LTBcIiAqbmdJZj1cImNvbnRlbnQ/LmNhdGVnb3J5ID09PSAnUmVzb3VyY2UnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwibXItMSBjdXN0b20taWNvbiByb3RhdGUtOTBcIj5jYWxsX3RvX2FjdGlvbjwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJub2R0cmFuc2xhdGVcIj5SZXNvdXJjZTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInR5cGUtY29udGFpbmVyIG1vZHVsZSBtdC0yIHNtOm10LTBcIiAqbmdJZj1cImNvbnRlbnQ/LmNhdGVnb3J5ID09PSAnQ29sbGVjdGlvbidcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJtci0xIGN1c3RvbS1pY29uIHJvdGF0ZS05MFwiPmNhbGxfdG9fYWN0aW9uPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5vZHRyYW5zbGF0ZVwiPk1vZHVsZTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInR5cGUtY29udGFpbmVyIGNvdXJzZSBtdC0yIHNtOm10LTBcIiAqbmdJZj1cImNvbnRlbnQ/LmNhdGVnb3J5ID09PSAnQ291cnNlJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm1yLTEgY3VzdG9tLWljb24gcm90YXRlLTkwXCI+Y2FsbF90b19hY3Rpb248L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibm9kdHJhbnNsYXRlXCI+Q291cnNlPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIE1pbGVzdG9uZSBCYWRnZSAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImlzTWlsZXN0b25lXCIgY2xhc3M9XCJtaWxlc3RvbmUtYmFkZ2UgbXQtMiBtYi0yXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1pbGVzdG9uZS1iYWRnZS10ZXh0IG5vZHRyYW5zbGF0ZVwiPk1pbGVzdG9uZSB7e2luZGV4IC0gMX19PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBNaWxlc3RvbmUgRGVzY3JpcHRpb24gKDMgbGluZXMgd2l0aCBlbGxpcHNpcykgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxwICpuZ0lmPVwiaXNNaWxlc3RvbmUgJiYgY29udGVudD8uZGVzY3JpcHRpb25cIiBjbGFzcz1cIm1pbGVzdG9uZS1kZXNjcmlwdGlvbiBtdC0yICBub2R0cmFuc2xhdGVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGNvbnRlbnQ/LmRlc2NyaXB0aW9uIH19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvcD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1yb3cgZ2FwLTMgaXRlbXMtY2VudGVyIGNvbnRlbnQta2V5LXZhbHVlcyBtdC0yXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCIhaXNNb2R1bGVcIiBhbHQ9XCJjb3Vyc2VcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidGltZS1pY29uIGljb24tY29sb3JcIj52aWRlb19saWJyYXJ5PC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgKm5nSWY9XCJpc01vZHVsZVwiIGFsdD1cIk1vZHVsZVwiIGNsYXNzPVwidGltZS1pY29uXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9tb2R1bGUuc3ZnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC14cyBub2R0cmFuc2xhdGVcIj57eyAoaGllcmFyY2h5TWFwRGF0YVtjb250ZW50Py5pZGVudGlmaWVyXT8uZHVyYXRpb24gfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxMjApfFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpcGVEdXJhdGlvblRyYW5zZm9ybTogJ2htcycgfX08L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudD8ubW9kdWxlQ291bnRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJwZXJpb2RcIj48L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQteHMgbm9kdHJhbnNsYXRlXCI+e3tjb250ZW50Py5tb2R1bGVDb3VudH19IHt7Y29udGVudD8ubW9kdWxlQ291bnQgPiAxP1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbW9kdWxlcycgOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbW9kdWxlJ319PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb250ZW50Py5sZWFmTm9kZXNDb3VudFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInBlcmlvZFwiPjwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC14cyBub2R0cmFuc2xhdGVcIj57e2NvbnRlbnQ/LmxlYWZOb2Rlc0NvdW50fX0ge3tjb250ZW50Py5sZWFmTm9kZXNDb3VudFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+MSA/ICdpdGVtcyc6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdpdGVtJ319PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gTWlsZXN0b25lIENvbXBsZXRpb24gUHJvZ3Jlc3MgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJpc01pbGVzdG9uZSAmJiBpc0Vucm9sbGVkICYmICFpc01pbGVzdG9uZUxvY2tlZFwiIGNsYXNzPVwibWlsZXN0b25lLXByb2dyZXNzIG10LTIgIGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktYmV0d2VlblwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1pbGVzdG9uZS1wcm9ncmVzcy10ZXh0IG5vZHRyYW5zbGF0ZVwiPnt7Z2V0TWlsZXN0b25lQ29tcGxldGVkQ291bnQoKX19IG9mXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tjb250ZW50Py5sZWFmTm9kZXNDb3VudCB8fCAwfX0gY29tcGxldGVkPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFZpZXcgQWNoaWV2ZW1lbnQgQnV0dG9uIGZvciBjb21wbGV0ZWQgbWlsZXN0b25lcyAtIE91dHNpZGUgY2xpY2thYmxlIGFyZWEgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaXNNaWxlc3RvbmUgJiYgaXNFbnJvbGxlZCAmJiAoZ2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcikgPj0gMTAwIHx8IGdldENvbXBsZXRpb25TdGF0dXMoY29udGVudD8uaWRlbnRpZmllcikgPT09IDIpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInZpZXctYWNoaWV2ZW1lbnQtY29udGFpbmVyIG10LTJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInZpZXctYWNoaWV2ZW1lbnQtYnRuXCIgW2Rpc2FibGVkXT1cImFjaGlldmVtZW50TG9hZGluZ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJ2aWV3TWlsZXN0b25lQWNoaWV2ZW1lbnQoJGV2ZW50KVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cIiFhY2hpZXZlbWVudExvYWRpbmdcIj5WaWV3IEFjaGlldmVtZW50PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNwaW5uZXIgKm5nSWY9XCJhY2hpZXZlbWVudExvYWRpbmdcIiBbZGlhbWV0ZXJdPVwiMTZcIiBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHJva2VXaWR0aF09XCIyXCIgY29sb3I9XCJwcmltYXJ5XCIgY2xhc3M9XCJpbmxpbmUtc3Bpbm5lclwiPjwvbWF0LXNwaW5uZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gVW5sb2NrIENyaXRlcmlhIE1lc3NhZ2UgZm9yIExvY2tlZCBNaWxlc3RvbmVzIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaXNNaWxlc3RvbmUgJiYgaXNFbnJvbGxlZCAmJiBpc01pbGVzdG9uZUxvY2tlZFwiIGNsYXNzPVwibWlsZXN0b25lLWxvY2tlZC1tZXNzYWdlIG10LTJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibG9ja2VkLWNyaXRlcmlhLXRleHQgbWF0LWNhcHRpb25cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBnZXRNaWxlc3RvbmVVbmxvY2tNZXNzYWdlKCkgfX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gRm9yIGNvdXJzZSBwcm9ncmVzcyB0byBiZSBzaG93biAtLT5cclxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNFbnJvbGxlZCAmJiAhaXNNaWxlc3RvbmVMb2NrZWQgJiYgIWlzUGFyZW50TWlsZXN0b25lTG9ja2VkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIWZvclByZXZpZXcgJiYgY29udGVudD8uaWRlbnRpZmllciAmJiBnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKSAmJiBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gJ0NvdXJzZSdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRDb21wbGV0aW9uU3RhdHVzKGNvbnRlbnQ/LmlkZW50aWZpZXIpID09IDJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LTFcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTIgbXItNCAgZmxleCBmbGV4LTEgZmxleC1jb2wgIHByb2dyZXNzLWNvbnRhaW5lclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1yb3cganVzdGlmeS1lbmQgdy1mdWxsIFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWF0LWJvZHktMiBub2R0cmFuc2xhdGUgXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7Z2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcil9fSU8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8d3Mtd2lkZ2V0LWNvbnRlbnQtcHJvZ3Jlc3MgW2NvbnRlbnRJZF09XCJjb250ZW50Py5wcm9ncmVzc1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Byb2dyZXNzXT1cImdldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcHJvZ3Jlc3NUeXBlXT1cIidwZXJjZW50YWdlJ1wiIFtjdXN0b21DbGFzc05hbWVdPVwiJ3ZpZXdlci1wcm9ncmVzcydcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvd3Mtd2lkZ2V0LWNvbnRlbnQtcHJvZ3Jlc3M+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudD8uaXNzdWVkQ2VydGlmaWNhdGVzSWRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwibWwtNSBjZXJ0aWZpY2F0ZS1idG5cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnZGlzYWJsZS1idG4nOiBkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZyB8fCBjb250ZW50Py5pc3N1ZWRDZXJ0aWZpY2F0ZXNJZH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCIhZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmcgJiYgZG93bmxvYWRDZXJ0aWZpY2F0ZShjb250ZW50Py5pc3N1ZWRDZXJ0aWZpY2F0ZXNJZCk7JGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSA8aW1nIHNyYz1cImZ1c2lvbi1hc3NldHMvaW1hZ2VzL2NlcnRpZmljYXRlLWljby5zdmdcIiB3aWR0aD1cIjI0XCIgaGVpZ2h0PVwiMjRcIj4gLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJub2R0cmFuc2xhdGVcIj5DZXJ0aWZpY2F0ZTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCIhZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1sLTJcIj5hcnJvd19kb3dud2FyZDwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNlbnRlciBmbGV4IGZsZXgtbWlkZGxlIGNlcnRpZmljYXRlLWxvYWRlclwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zcGlubmVyIHN0cm9rZVdpZHRoPVwiMlwiIHN0cm9rZT1cIid3aGl0ZSdcIiBjbGFzcz1cIndoaXRlLXNwaW5uZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2RpYW1ldGVyXT1cIjE2XCI+PC9tYXQtc3Bpbm5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSA8Y2lyY2xlLXByb2dyZXNzIGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgcHJvZ3Jlc3NcIiBbcGVyY2VudF09XCIxMDBcIiBbcmFkaXVzXT1cIjEyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlV2lkdGhdPVwiM1wiIFtpbm5lclN0cm9rZVdpZHRoXT1cIjNcIiBbc3BhY2VdPVwiLTNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3V0ZXJTdHJva2VDb2xvcl09XCJwcm9ncmVzc0NvbG9yKClcIiBbaW5uZXJTdHJva2VDb2xvcl09XCIncmdiYSgwLDAsMCwuMTYpJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthbmltYXRpb25dPVwidHJ1ZVwiIFthbmltYXRpb25EdXJhdGlvbl09XCIzMDBcIiBbc2hvd1RpdGxlXT1cImZhbHNlXCIgW3Nob3dVbml0c109XCJmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93U3VidGl0bGVdPVwiZmFsc2VcIiBbc2hvd0lubmVyU3Ryb2tlXT1cInRydWVcIiBbY2xvY2t3aXNlXT1cInRydWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYmFja2dyb3VuZE9wYWNpdHldPVwiMFwiIFtiYWNrZ3JvdW5kR3JhZGllbnRdPVwiZmFsc2VcIiBbYmFja2dyb3VuZFN0cm9rZVdpZHRoXT1cIjNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2hvd1plcm9PdXRlclN0cm9rZV09ZmFsc2UgW2JhY2tncm91bmRQYWRkaW5nXT1cIi05XCIgW3N0YXJ0RnJvbVplcm9dPVwiZmFsc2VcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYmFja2dyb3VuZFBhZGRpbmddPVwiMFwiIFtpbWFnZUhlaWdodF09XCIyNFwiIFtpbWFnZVdpZHRoXT1cIjI0XCIgW3Nob3dCYWNrZ3JvdW5kXT1cImZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlTGluZWNhcF09XCInYnV0dCdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2NpcmNsZS1wcm9ncmVzcz4gLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRDb21wbGV0aW9uU3RhdHVzKGNvbnRlbnQ/LmlkZW50aWZpZXIpIDwgMlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtMVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtMiBtci00ICBmbGV4IGZsZXgtMSBmbGV4LWNvbCAgcHJvZ3Jlc3MtY29udGFpbmVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXJvdyBqdXN0aWZ5LWVuZCB3LWZ1bGwgd3MtbWF0LWJsYWNrLXRleHRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1hdC1ib2R5LTIgIHdzLW1hdC1ibGFjay10ZXh0IG5vZHRyYW5zbGF0ZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2dldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpfX0lPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHdzLXdpZGdldC1jb250ZW50LXByb2dyZXNzIFtjb250ZW50SWRdPVwiY29udGVudD8ucHJvZ3Jlc3NcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwcm9ncmVzc109XCJnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Byb2dyZXNzVHlwZV09XCIncGVyY2VudGFnZSdcIiBbY3VzdG9tQ2xhc3NOYW1lXT1cIid2aWV3ZXItcHJvZ3Jlc3MnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3dzLXdpZGdldC1jb250ZW50LXByb2dyZXNzPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnQ/Lmlzc3VlZENlcnRpZmljYXRlc0lkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YSBjbGFzcz1cIm1sLTUgY2VydGlmaWNhdGUtYnRuXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J2Rpc2FibGUtYnRuJzogZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmcgfHwgY29udGVudD8uaXNzdWVkQ2VydGlmaWNhdGVzSWR9XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiIWRvd25sb2FkQ2VydGlmaWNhdGVMb2FkaW5nICYmIGRvd25sb2FkQ2VydGlmaWNhdGUoY29udGVudD8uaXNzdWVkQ2VydGlmaWNhdGVzSWQpOyRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPGltZyBzcmM9XCJmdXNpb24tYXNzZXRzL2ltYWdlcy9jZXJ0aWZpY2F0ZS1pY28uc3ZnXCIgd2lkdGg9XCIyNFwiIGhlaWdodD1cIjI0XCI+IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibm9kdHJhbnNsYXRlXCI+Q2VydGlmaWNhdGU8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwiIWRvd25sb2FkQ2VydGlmaWNhdGVMb2FkaW5nXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJtbC0yXCI+YXJyb3dfZG93bndhcmQ8L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjZW50ZXIgZmxleCBmbGV4LW1pZGRsZSBjZXJ0aWZpY2F0ZS1sb2FkZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImRvd25sb2FkQ2VydGlmaWNhdGVMb2FkaW5nXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtc3Bpbm5lciBzdHJva2VXaWR0aD1cIjJcIiBzdHJva2U9XCInd2hpdGUnXCIgY2xhc3M9XCJ3aGl0ZS1zcGlubmVyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaWFtZXRlcl09XCIxNlwiPjwvbWF0LXNwaW5uZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2E+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VlLWFsbC1jb250YWluZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGEgaHJlZj1cImphdmFzY3JpcHQ6dm9pZCgwKVwiIHJvbGU9XCJidXR0b25cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNvbnRlbnQudmlld0NoaWxkcmVuID0gIWNvbnRlbnQudmlld0NoaWxkcmVuOyBleHBhbmRBY3RpdmUgPSBmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInNlZS1hbGwtYnRuIHRhYiBjdXN0b20tY2hldnJvbiBjdXN0b21pY29uXCIgbWF0LWJ1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIiFjb250ZW50LnZpZXdDaGlsZHJlbiAmJiAhaXNNb2R1bGVcIj5rZXlib2FyZF9hcnJvd19kb3duPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cImNvbnRlbnQudmlld0NoaWxkcmVuICYmICFpc01vZHVsZVwiPmtleWJvYXJkX2Fycm93X3VwPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIiFjb250ZW50LnZpZXdDaGlsZHJlbiAmJiBpc01vZHVsZVwiPmFkZDwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCJjb250ZW50LnZpZXdDaGlsZHJlbiAmJiBpc01vZHVsZVwiPnJlbW92ZTwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiY2hpbGQtd3JhcHBlciAgXCIgKm5nSWY9XCJjb250ZW50LnZpZXdDaGlsZHJlblwiIFtuZ0NsYXNzXT1cInsnb3Blbic6IGNvbnRlbnQudmlld0NoaWxkcmVuLFxyXG4gICAgICAgICAgICAnY2xvc2UnOiAhY29udGVudC52aWV3Q2hpbGRyZW4sXHJcbiAgICAgICAgICAgICdjb3Vyc2UnOiFpc01vZHVsZSxcclxuICAgICAgICAgICAgJ21vZHVsZSc6IGlzTW9kdWxlfVwiIFtAcGFuZWxJbk91dF0+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjaGlsZHJlbi1jb250YWluZXJcIiBbbmdDbGFzc109XCJ7J21vZHVsZSc6IGlzTW9kdWxlLCAnJzogIWlzTW9kdWxlfVwiPlxyXG4gICAgICAgICAgICAgICAgPHdzLXdpZGdldC1hcHAtdG9jLWNvbnRlbnQtY2FyZC12MiBbZm9yUHJldmlld109XCJmb3JQcmV2aWV3XCIgW2NvbXBvbmVudE5hbWVdPVwiY29tcG9uZW50TmFtZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgW2NvbnRlbnRdPVwiY2hpbGRcIiBbZXhwYW5kQWxsXT1cImV4cGFuZEFsbFwiIFtyb290SWRdPVwicm9vdElkXCIgW2JhdGNoSWRdPVwiYmF0Y2hJZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgW3Jvb3RDb250ZW50VHlwZV09XCJyb290Q29udGVudFR5cGVcIiBbaW5kZXhdPVwiaisxXCIgW2Jhc2VDb250ZW50UmVhZERhdGFdPVwiYmFzZUNvbnRlbnRSZWFkRGF0YVwiXHJcbiAgICAgICAgICAgICAgICAgICAgW3BhdGhTZXRdPVwicGF0aFNldFwiIFtoaWVyYXJjaHlNYXBEYXRhXT1cImhpZXJhcmNoeU1hcERhdGFcIiBbYmF0Y2hEYXRhXT1cImJhdGNoRGF0YVwiXHJcbiAgICAgICAgICAgICAgICAgICAgW21sQ291cnNlXT1cIm1sQ291cnNlXCIgW3BhcmVudE1pbGVzdG9uZUxvY2tlZF09XCJpc01pbGVzdG9uZUxvY2tlZCB8fCBpc1BhcmVudE1pbGVzdG9uZUxvY2tlZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGNoaWxkIG9mIGNvbnRlbnQ/LmNoaWxkcmVuOyB0cmFja0J5OiBjb250ZW50VHJhY2tCeTsgbGV0IGo9IGluZGV4O2xldCBpc0ZpcnN0ID0gZmlyc3RcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnbW9kdWxlQ2FyZCc6IGNoZWNrSXNNb2R1bGUoY2hpbGQpLCAncmVzb3VyY2VDYXJkJzogIWNoZWNrSXNNb2R1bGUoY2hpbGQpLCAnZmlyc3QnOiBpc0ZpcnN0fVwiPlxyXG4gICAgICAgICAgICAgICAgPC93cy13aWRnZXQtYXBwLXRvYy1jb250ZW50LWNhcmQtdjI+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgPC9uZy1jb250YWluZXI+XHJcbjwvbmctdGVtcGxhdGU+XHJcblxyXG5cclxuPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzUHJlQXNzZXNzbWVudFwiPlxyXG4gICAgPGRpdiBjbGFzcz1cImNvbGxlY3Rpb24td3JhcHBlciBwLTQgZmxleCBmbGV4LWNvbCBwb3NpdGlvbi1yZWxhdGl2ZVwiIFtuZ0NsYXNzXT1cInsnb3Blbic6IGNoZWNrKGNvbnRlbnQpLFxyXG4gICAgICAgICdjb3Vyc2UnOiFpc01vZHVsZSwgJ21vZHVsZSc6IGlzTW9kdWxlLFxyXG4gICAgICAgICdjb250ZW50LWFjdGl2ZSc6IHBhdGhTZXQ/Lmhhcyhjb250ZW50LmlkZW50aWZpZXIpfVwiPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJjYXJkLWNvbGxlY3Rpb24gdy1hdXRvIHNtOnctMTAwIHBhZGRpbmctcmlnaHQteGxcIj5cclxuICAgICAgICAgICAgPCEtLSA8aW1nIGNsYXNzPVwiY2FyZC10aHVtYm5haWwgd3MtbWF0LXByaW1hcnktbGl0ZS1iYWNrZ3JvdW5kXCIgW3NyY109XCJjb250ZW50Py5hcHBJY29uXCIgYWx0PVwiVGh1bWJuYWlsXCJcclxuICAgICAgICAoY2xpY2spPVwiY29udGVudC52aWV3Q2hpbGRyZW4gPSAhY29udGVudC52aWV3Q2hpbGRyZW5cIiBbd3NVdGlsc0RlZmF1bHRUaHVtYm5haWxdPVwiZGVmYXVsdFRodW1ibmFpbFwiIC8+IC0tPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCBmbGV4LXdyYXAgZmxleC1iZXR3ZWVuIHdpZHRoLWV4cGFuZCBwci0wIHctMTAwIFwiPlxyXG5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXRydW5jYXRlXCIgW25nQ2xhc3NdPVwieydjdXJzb3ItcG9pbnRlcic6ICFpc0VuYWJsZWR9XCJcclxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiY29udGVudC52aWV3Q2hpbGRyZW4gPSAhY29udGVudC52aWV3Q2hpbGRyZW5cIj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBzbTpmbGV4LXJvdyBmbGV4LXdyYXBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIiFmb3JQcmV2aWV3ICYmIGNvbnRlbnQ/LmlkZW50aWZpZXIgJiYgZ2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcikgOyBlbHNlIGVsc2VCbG9ja1wiPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0Q29tcGxldGlvblN0YXR1cyhjb250ZW50LmlkZW50aWZpZXIpID09IDJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbXBsZXRlZCBtci0yXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cImNvbXBsZXRlZC1pY29uXCIgW2NvbG9yXT1cImJsdWVcIj5jaGVja19jaXJjbGU8L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRDb21wbGV0aW9uU3RhdHVzKGNvbnRlbnQ/LmlkZW50aWZpZXIpIDwgMlwiPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZS1wcm9ncmVzcyBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHByb2dyZXNzIG1yLTFcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BlcmNlbnRdPVwiZ2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcilcIiBbcmFkaXVzXT1cIjEwXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZVdpZHRoXT1cIjJcIiBbaW5uZXJTdHJva2VXaWR0aF09XCIyXCIgW3NwYWNlXT1cIi0yXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZUNvbG9yXT1cInByb2dyZXNzQ29sb3IyKClcIiBbaW5uZXJTdHJva2VDb2xvcl09XCIncmdiYSgwLCAwLCAwLCAwLjE2KSdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2FuaW1hdGlvbl09XCJ0cnVlXCIgW2FuaW1hdGlvbkR1cmF0aW9uXT1cIjI1MFwiIFtzaG93VGl0bGVdPVwiZmFsc2VcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dVbml0c109XCJmYWxzZVwiIFtzaG93U3VidGl0bGVdPVwiZmFsc2VcIiBbc2hvd0lubmVyU3Ryb2tlXT1cInRydWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Nsb2Nrd2lzZV09XCJ0cnVlXCIgW2JhY2tncm91bmRPcGFjaXR5XT1cIjBcIiBbYmFja2dyb3VuZEdyYWRpZW50XT1cImZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtiYWNrZ3JvdW5kU3Ryb2tlV2lkdGhdPVwiM1wiIG1hdFRvb2x0aXA9XCJJbiBwcm9ncmVzc1wiIFtzaG93WmVyb091dGVyU3Ryb2tlXT1mYWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2JhY2tncm91bmRQYWRkaW5nXT1cIi03XCIgW3N0YXJ0RnJvbVplcm9dPVwiZmFsc2VcIiBbYmFja2dyb3VuZFBhZGRpbmddPVwiMFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaW1hZ2VIZWlnaHRdPVwiMThcIiBbaW1hZ2VXaWR0aF09XCIxOFwiIFtzaG93QmFja2dyb3VuZF09XCJmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3V0ZXJTdHJva2VMaW5lY2FwXT1cIididXR0J1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2NpcmNsZS1wcm9ncmVzcz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNlbHNlQmxvY2s+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZS1wcm9ncmVzcyBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHByb2dyZXNzIG1yLTFcIiBbcGVyY2VudF09XCIwXCIgW3JhZGl1c109XCIxMVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZVdpZHRoXT1cIjJcIiBbaW5uZXJTdHJva2VXaWR0aF09XCIyXCIgW291dGVyU3Ryb2tlQ29sb3JdPVwiJyM4MDgwODAnXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lubmVyU3Ryb2tlQ29sb3JdPVwiJyM4MDgwODAnXCIgW2FuaW1hdGlvbl09XCJ0cnVlXCIgW3NwYWNlXT1cIi0yXCIgW3Nob3dVbml0c109XCJmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthbmltYXRpb25EdXJhdGlvbl09XCIyNTBcIiBbc2hvd1RpdGxlXT1cImZhbHNlXCIgW2JhY2tncm91bmRQYWRkaW5nXT1cIjBcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYmFja2dyb3VuZFBhZGRpbmddPVwiLTlcIiBbb3V0ZXJTdHJva2VMaW5lY2FwXT1cIididXR0J1wiIG1hdFRvb2x0aXA9XCJOb3Qgc3RhcnRlZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93U3VidGl0bGVdPVwiZmFsc2VcIiBbc2hvd0lubmVyU3Ryb2tlXT1cInRydWVcIiBbY2xvY2t3aXNlXT1cInRydWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaW1hZ2VIZWlnaHRdPVwiMjJcIiBbaW1hZ2VXaWR0aF09XCIyMlwiIFtzaG93QmFja2dyb3VuZF09XCJmYWxzZVwiPjwvY2lyY2xlLXByb2dyZXNzPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgW25nQ2xhc3NdPVwieydjb2xsZWN0aW9uLWFjdGl2ZS1jbGFzcyc6IHBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKX1cIj48L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSA8cCBjbGFzcz1cIm1hcmdpbi1yZW1vdmUgdGV4dC10cnVuY2F0ZSBtYXQtc3ViaGVhZGluZy0xIGZsZXgtYXV0byBmb250LWJvbGQgbm9kdHJhbnNsYXRlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsndGV4dC1hY3RpdmUnOiBwYXRoU2V0Py5oYXMoY29udGVudC5pZGVudGlmaWVyKX1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7aW5kZXh9fS4ge3sgY29udGVudD8ubmFtZSB8IHRydW5jYXRlOjUwIH19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvcD4gLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwibWFyZ2luLXJlbW92ZSB0ZXh0LXRydW5jYXRlIG1hdC1zdWJoZWFkaW5nLTEgZmxleC1hdXRvIGZvbnQtYm9sZCBub2R0cmFuc2xhdGVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmRpc2FibGVkXT1cIm51bGxcIiBbbmdDbGFzc109XCJ7J21sLTMnOiBpc0Vucm9sbGVkfVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcm91dGVyTGlua109XCIoaXNBbGxvd2VkICYmICFmb3JQcmV2aWV3ICYmIGlzRW5hYmxlZCkgPyByZXNvdXJjZUxpbmsudXJsIDogbnVsbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcXVlcnlQYXJhbXNdPVwiY29tcHV0ZWRRdWVyeVBhcmFtc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSB7e2NvbnRlbnQ/LmNvdXJzZUNhdGVnb3J5fX0gLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IFtuZ0NsYXNzXT1cInsncmVzb3VyY2UtYWN0aXZlJzogcGF0aFNldD8uaGFzKGNvbnRlbnQ/LmlkZW50aWZpZXIpfVwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtdHJ1bmNhdGUgXCIgW25nQ2xhc3NdPVwieydjdXJzb3ItcG9pbnRlcic6ICFpc0VuYWJsZWR9XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwicmFpc2VUZWxlbWV0cnkoKTsgY2hhbmdlUmVzb3VyY2UoKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sIHNtOmZsZXgtcm93IGZsZXgtd3JhcFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cIm1hcmdpbi1yZW1vdmUgdGV4dC10cnVuY2F0ZSBtYXQtYm9keS0yIGZsZXgtYXV0byBmb250LWJvbGQgbm9kdHJhbnNsYXRlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsndGV4dC1hY3RpdmUnOiBwYXRoU2V0Py5oYXMoY29udGVudD8uaWRlbnRpZmllcil9XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIDxtYXQtaWNvbiBjbGFzcz1cIm1hcmdpbi1yaWdodC14cyByYWRpb2J0biB0aW1lLWljb25cIj5yYWRpb19idXR0b25fdW5jaGVja2VkIDwvbWF0LWljb24+IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tpbmRleH19LiB7eyBjb250ZW50Py5uYW1lIHwgdHJ1bmNhdGU6NTAgfX1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvcD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjb250ZW50LXR5cGUgb3B0aW9uYWwtc3BhbiBub2R0cmFuc2xhdGVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5vcHRpb25hbFJlYWRpbmdcIj57eyAncGxheWVyYnJpZWYub3B0aW9uYWwnIHwgdHJhbnNsYXRlIHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlY2FzZX19IDwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIGZvciBkZWZhdWx0IGdyZXkgaWNvbnMgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFwYXRoU2V0Py5oYXMoY29udGVudD8uaWRlbnRpZmllcilcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlc2ljb25zIHdzLW1hdC1ibGFjazYwLXRleHRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvdmlkZW8uc3ZnXCIgYWx0PVwiVmlkZW9cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIiAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAndmlkZW8vbXA0JyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ3ZpZGVvL3gteW91dHViZScgfHxcclxuICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ/Lm1pbWVUeXBlID09PSdhcHBsaWNhdGlvbi94LW1wZWdVUkwnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2F1ZGlvLnN2Z1wiIGFsdD1cIkF1ZGlvXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXVkaW8vbXBlZydcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvcGRmLnN2Z1wiIGFsdD1cIlBERlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3BkZidcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9yZXNvdXJjZS5zdmdcIiBhbHQ9XCJTdXJ2ZXlcIiBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcclxuICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vc3VydmV5J1wiPiAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvbGluay5zdmdcIiBhbHQ9XCJJbnRlcmFjdGl2ZUNvbnRlbnRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi92bmQuZWtzdGVwLmh0bWwtYXJjaGl2ZScgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICd0ZXh0L3gtdXJsJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9hc3Nlc3NtZW50LnN2Z1wiIGFsdD1cIkFzc2Vzc21lbnRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9qc29uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3F1aXonIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLnN1bmJpcmQucXVlc3Rpb25zZXQnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2ltYWdlLnN2Z1wiIGFsdD1cIkltYWdlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnaW1hZ2UvcG5nJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2ltYWdlL2pwZWcnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2NvbnRlbnRfY29weS5zdmdcIiBjbGFzcz1cImNvbnRlbnRpY29uXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbHQ9XCJDb3Vyc2VcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5la3N0ZXAuY29udGVudC1jb2xsZWN0aW9uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3N1cnZleSdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvbW9kdWxlLnN2Z1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiIGFsdD1cIm9mZmxpbmUgc2Vzc2lvbnNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL29mZmxpbmUnXCI+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5DT01QX0FTU0VTU01FTlQgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuU1RBTkRBTE9ORV9BU1NFU1NNRU5UIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFXCI+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicmVzb3VyY2VEdXJhdGlvbiB3cy1tYXQtYmxhY2s2MC10ZXh0IG5vZHRyYW5zbGF0ZVwiPnt7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ/Lm1heFF1ZXN0aW9ucyB9fSB7eyAncGxheWVyYnJpZWYucXVlc3Rpb25zJyB8IHRyYW5zbGF0ZSB8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlY2FzZX19PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIShjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuQ09NUF9BU1NFU1NNRU5UIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlNUQU5EQUxPTkVfQVNTRVNTTUVOVCB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5QUkFDVElDRV9SRVNPVVJDRSlcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInJlc291cmNlRHVyYXRpb24gd3MtbWF0LWJsYWNrNjAtdGV4dCBub2R0cmFuc2xhdGVcIj57e1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29udGVudD8uZHVyYXRpb258fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWVyYXJjaHlNYXBEYXRhW2NvbnRlbnQ/LmlkZW50aWZpZXJdPy5leHBlY3RlZER1cmF0aW9uIHx8IDApfFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXBlRHVyYXRpb25UcmFuc2Zvcm06XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdobXMnXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH19PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIGZvciB3aGl0ZSBpY29ucyB3aGVuIGNvbnRlbnQgaGlnaGxpZ2h0ZWQgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVzaWNvbnMgd3MtbWF0LXdoaXRlLXRleHRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L3doaXRlL3ZpZGVvLnN2Z1wiIGFsdD1cIlZpZGVvXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCIgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ3ZpZGVvL21wNCcgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICd2aWRlby94LXlvdXR1YmUnIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICBjb250ZW50Py5taW1lVHlwZSA9PT0nYXBwbGljYXRpb24veC1tcGVnVVJMJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvd2hpdGUvYXVkaW8uc3ZnXCIgYWx0PVwiQXVkaW9cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhdWRpby9tcGVnJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvd2hpdGUvcGRmLnN2Z1wiIGFsdD1cIlBERlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3BkZidcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvd2hpdGUvcmVzb3VyY2Uuc3ZnXCIgYWx0PVwiU3VydmV5XCIgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXHJcbiAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3N1cnZleSdcIj4gLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9saW5rLnN2Z1wiIGFsdD1cIkludGVyYWN0aXZlQ29udGVudFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5la3N0ZXAuaHRtbC1hcmNoaXZlJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ3RleHQveC11cmwnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9hc3Nlc3NtZW50LnN2Z1wiIGFsdD1cIkFzc2Vzc21lbnRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9qc29uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3F1aXonIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLnN1bmJpcmQucXVlc3Rpb25zZXQnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2ltYWdlLnN2Z1wiIGFsdD1cIkltYWdlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnaW1hZ2UvcG5nJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2ltYWdlL2pwZWcnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9jb250ZW50X2NvcHkuc3ZnXCIgY2xhc3M9XCJjb250ZW50aWNvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWx0PVwiQ291cnNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi92bmQuZWtzdGVwLmNvbnRlbnQtY29sbGVjdGlvbicgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9zdXJ2ZXknXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9tb2R1bGUuc3ZnXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCIgYWx0PVwib2ZmbGluZSBzZXNzaW9uc1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vb2ZmbGluZSdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuQ09NUF9BU1NFU1NNRU5UIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlNUQU5EQUxPTkVfQVNTRVNTTUVOVCB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5QUkFDVElDRV9SRVNPVVJDRVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicmVzb3VyY2VEdXJhdGlvbiB3cy1tYXQtd2hpdGUtdGV4dCBub2R0cmFuc2xhdGVcIj57e1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50Py5tYXhRdWVzdGlvbnMgfX0ge3sgJ3BsYXllcmJyaWVmLnF1ZXN0aW9ucycgfCB0cmFuc2xhdGUgfFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZWNhc2V9fTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiEoY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5GSU5BTF9BU1NFU1NNRU5UIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkNPTVBfQVNTRVNTTUVOVCB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5TVEFOREFMT05FX0FTU0VTU01FTlQgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuUFJBQ1RJQ0VfUkVTT1VSQ0UpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJyZXNvdXJjZUR1cmF0aW9uIHdzLW1hdC13aGl0ZS10ZXh0IG5vZHRyYW5zbGF0ZVwiPnt7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjb250ZW50Py5kdXJhdGlvbnx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZXJhcmNoeU1hcERhdGFbY29udGVudD8uaWRlbnRpZmllcl0/LmV4cGVjdGVkRHVyYXRpb24gfHwgMCl8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpcGVEdXJhdGlvblRyYW5zZm9ybTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2htcydcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIDxkaXYgY2xhc3M9XCJ0eXBlLWNvbnRhaW5lciByZXNvdXJjZSBtdC0yIHNtOm10LTBcIiAqbmdJZj1cImNvbnRlbnQ/LmNhdGVnb3J5ID09PSAnUmVzb3VyY2UnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJtci0xIGN1c3RvbS1pY29uIHJvdGF0ZS05MFwiPmNhbGxfdG9fYWN0aW9uPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibm9kdHJhbnNsYXRlXCI+UmVzb3VyY2U8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidHlwZS1jb250YWluZXIgbW9kdWxlIG10LTIgc206bXQtMFwiICpuZ0lmPVwiY29udGVudD8uY2F0ZWdvcnkgPT09ICdDb2xsZWN0aW9uJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwibXItMSBjdXN0b20taWNvbiByb3RhdGUtOTBcIj5jYWxsX3RvX2FjdGlvbjwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5vZHRyYW5zbGF0ZVwiPk1vZHVsZTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0eXBlLWNvbnRhaW5lciBjb3Vyc2UgbXQtMiBzbTptdC0wXCIgKm5nSWY9XCJjb250ZW50Py5jYXRlZ29yeSA9PT0gJ0NvdXJzZSdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm1yLTEgY3VzdG9tLWljb24gcm90YXRlLTkwXCI+Y2FsbF90b19hY3Rpb248L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJub2R0cmFuc2xhdGVcIj5Db3Vyc2U8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PiAtLT5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDwhLS0gRm9yIGNvdXJzZSBwcm9ncmVzcyB0byBiZSBzaG93biAtLT5cclxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxyXG4gICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIiFmb3JQcmV2aWV3ICYmIGNvbnRlbnQ/LmlkZW50aWZpZXIgJiYgZ2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcilcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldENvbXBsZXRpb25TdGF0dXMoY29udGVudD8uaWRlbnRpZmllcikgPT0gMlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC0xXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTIgbXItNCAgZmxleCBmbGV4LTEgZmxleC1jb2wgIHByb2dyZXNzLWNvbnRhaW5lclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXJvdyBqdXN0aWZ5LWVuZCB3LWZ1bGwgXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1hdC1ib2R5LTIgbm9kdHJhbnNsYXRlIFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7Z2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcil9fSU8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHdzLXdpZGdldC1jb250ZW50LXByb2dyZXNzIFtjb250ZW50SWRdPVwiY29udGVudD8ucHJvZ3Jlc3NcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Byb2dyZXNzXT1cImdldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwcm9ncmVzc1R5cGVdPVwiJ3BlcmNlbnRhZ2UnXCIgW2N1c3RvbUNsYXNzTmFtZV09XCIndmlld2VyLXByb2dyZXNzJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3dzLXdpZGdldC1jb250ZW50LXByb2dyZXNzPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb250ZW50Py5pc3N1ZWRDZXJ0aWZpY2F0ZXNJZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YSBjbGFzcz1cIm1sLTUgY2VydGlmaWNhdGUtYnRuXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnZGlzYWJsZS1idG4nOiBkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZyB8fCBjb250ZW50Py5pc3N1ZWRDZXJ0aWZpY2F0ZXNJZH1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIiFkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZyAmJiBkb3dubG9hZENlcnRpZmljYXRlKGNvbnRlbnQ/Lmlzc3VlZENlcnRpZmljYXRlc0lkKTskZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPGltZyBzcmM9XCJmdXNpb24tYXNzZXRzL2ltYWdlcy9jZXJ0aWZpY2F0ZS1pY28uc3ZnXCIgd2lkdGg9XCIyNFwiIGhlaWdodD1cIjI0XCI+IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJub2R0cmFuc2xhdGVcIj5DZXJ0aWZpY2F0ZTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIiFkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJtbC0yXCI+YXJyb3dfZG93bndhcmQ8L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNlbnRlciBmbGV4IGZsZXgtbWlkZGxlIGNlcnRpZmljYXRlLWxvYWRlclwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtc3Bpbm5lciBzdHJva2VXaWR0aD1cIjJcIiBzdHJva2U9XCInd2hpdGUnXCIgY2xhc3M9XCJ3aGl0ZS1zcGlubmVyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2RpYW1ldGVyXT1cIjE2XCI+PC9tYXQtc3Bpbm5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2E+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPGNpcmNsZS1wcm9ncmVzcyBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHByb2dyZXNzXCIgW3BlcmNlbnRdPVwiMTAwXCIgW3JhZGl1c109XCIxMlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlV2lkdGhdPVwiM1wiIFtpbm5lclN0cm9rZVdpZHRoXT1cIjNcIiBbc3BhY2VdPVwiLTNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZUNvbG9yXT1cInByb2dyZXNzQ29sb3IoKVwiIFtpbm5lclN0cm9rZUNvbG9yXT1cIidyZ2JhKDAsMCwwLC4xNiknXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYW5pbWF0aW9uXT1cInRydWVcIiBbYW5pbWF0aW9uRHVyYXRpb25dPVwiMzAwXCIgW3Nob3dUaXRsZV09XCJmYWxzZVwiIFtzaG93VW5pdHNdPVwiZmFsc2VcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93U3VidGl0bGVdPVwiZmFsc2VcIiBbc2hvd0lubmVyU3Ryb2tlXT1cInRydWVcIiBbY2xvY2t3aXNlXT1cInRydWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtiYWNrZ3JvdW5kT3BhY2l0eV09XCIwXCIgW2JhY2tncm91bmRHcmFkaWVudF09XCJmYWxzZVwiIFtiYWNrZ3JvdW5kU3Ryb2tlV2lkdGhdPVwiM1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3daZXJvT3V0ZXJTdHJva2VdPWZhbHNlIFtiYWNrZ3JvdW5kUGFkZGluZ109XCItOVwiIFtzdGFydEZyb21aZXJvXT1cImZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYmFja2dyb3VuZFBhZGRpbmddPVwiMFwiIFtpbWFnZUhlaWdodF09XCIyNFwiIFtpbWFnZVdpZHRoXT1cIjI0XCIgW3Nob3dCYWNrZ3JvdW5kXT1cImZhbHNlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3V0ZXJTdHJva2VMaW5lY2FwXT1cIididXR0J1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9jaXJjbGUtcHJvZ3Jlc3M+IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldENvbXBsZXRpb25TdGF0dXMoY29udGVudD8uaWRlbnRpZmllcikgPCAyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LTFcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtMiBtci00ICBmbGV4IGZsZXgtMSBmbGV4LWNvbCAgcHJvZ3Jlc3MtY29udGFpbmVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtcm93IGp1c3RpZnktZW5kIHctZnVsbCB3cy1tYXQtYmxhY2stdGV4dFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtYXQtYm9keS0yICB3cy1tYXQtYmxhY2stdGV4dCBub2R0cmFuc2xhdGVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2dldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpfX0lPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx3cy13aWRnZXQtY29udGVudC1wcm9ncmVzcyBbY29udGVudElkXT1cImNvbnRlbnQ/LnByb2dyZXNzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwcm9ncmVzc109XCJnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcHJvZ3Jlc3NUeXBlXT1cIidwZXJjZW50YWdlJ1wiIFtjdXN0b21DbGFzc05hbWVdPVwiJ3ZpZXdlci1wcm9ncmVzcydcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC93cy13aWRnZXQtY29udGVudC1wcm9ncmVzcz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudD8uaXNzdWVkQ2VydGlmaWNhdGVzSWRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJtbC01IGNlcnRpZmljYXRlLWJ0blwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J2Rpc2FibGUtYnRuJzogZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmcgfHwgY29udGVudD8uaXNzdWVkQ2VydGlmaWNhdGVzSWR9XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCIhZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmcgJiYgZG93bmxvYWRDZXJ0aWZpY2F0ZShjb250ZW50Py5pc3N1ZWRDZXJ0aWZpY2F0ZXNJZCk7JGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIDxpbWcgc3JjPVwiZnVzaW9uLWFzc2V0cy9pbWFnZXMvY2VydGlmaWNhdGUtaWNvLnN2Z1wiIHdpZHRoPVwiMjRcIiBoZWlnaHQ9XCIyNFwiPiAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibm9kdHJhbnNsYXRlXCI+Q2VydGlmaWNhdGU8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCIhZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwibWwtMlwiPmFycm93X2Rvd253YXJkPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjZW50ZXIgZmxleCBmbGV4LW1pZGRsZSBjZXJ0aWZpY2F0ZS1sb2FkZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNwaW5uZXIgc3Ryb2tlV2lkdGg9XCIyXCIgc3Ryb2tlPVwiJ3doaXRlJ1wiIGNsYXNzPVwid2hpdGUtc3Bpbm5lclwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaWFtZXRlcl09XCIxNlwiPjwvbWF0LXNwaW5uZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgICAgICAgICAgICAgPCEtLSA8ZGl2IGNsYXNzPVwic2VlLWFsbC1jb250YWluZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICA8YSBocmVmPVwiamF2YXNjcmlwdDp2b2lkKDApXCIgcm9sZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJjb250ZW50LnZpZXdDaGlsZHJlbiA9ICFjb250ZW50LnZpZXdDaGlsZHJlbjsgZXhwYW5kQWN0aXZlID0gZmFsc2VcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInNlZS1hbGwtYnRuIHRhYiBjdXN0b20tY2hldnJvbiBjdXN0b21pY29uXCIgbWF0LWJ1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwiIWNvbnRlbnQudmlld0NoaWxkcmVuICYmICFpc01vZHVsZVwiPmtleWJvYXJkX2Fycm93X2Rvd248L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCJjb250ZW50LnZpZXdDaGlsZHJlbiAmJiAhaXNNb2R1bGVcIj5rZXlib2FyZF9hcnJvd191cDwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIiFjb250ZW50LnZpZXdDaGlsZHJlbiAmJiBpc01vZHVsZVwiPmFkZDwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cImNvbnRlbnQudmlld0NoaWxkcmVuICYmIGlzTW9kdWxlXCI+cmVtb3ZlPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICA8L2E+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj4gLS0+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcblxyXG48L25nLWNvbnRhaW5lcj4iXX0=
1
+ import { Component, Input } from '@angular/core';
2
+ import { NsContent } from '../../../../_services/widget-content.model';
3
+ import { viewerRouteGenerator } from '../../../../_services/viewer-route-util';
4
+ import { WsEvents } from '@sunbird-cb/utils-v2';
5
+ import { CertificateDialogComponent } from '../../certificate-dialog/certificate-dialog.component';
6
+ import { animate, style, transition, trigger } from '@angular/animations';
7
+ /* tslint:disable*/
8
+ import _ from 'lodash';
9
+ import moment from 'moment';
10
+ import * as i0 from "@angular/core";
11
+ import * as i1 from "@sunbird-cb/utils-v2";
12
+ import * as i2 from "@angular/material/legacy-dialog";
13
+ import * as i3 from "../../../../services/certificate.service";
14
+ import * as i4 from "../../../../services/app-toc.service";
15
+ import * as i5 from "@sunbird-cb/consumption";
16
+ import * as i6 from "../../../../services/resource-download-helper.service";
17
+ import * as i7 from "@angular/material/legacy-snack-bar";
18
+ import * as i8 from "@angular/common";
19
+ import * as i9 from "@angular/router";
20
+ import * as i10 from "@angular/material/icon";
21
+ import * as i11 from "@angular/material/menu";
22
+ import * as i12 from "@angular/material/progress-spinner";
23
+ import * as i13 from "../../content-progress/content-progress.component";
24
+ import * as i14 from "ng-circle-progress";
25
+ import * as i15 from "@angular/material/legacy-tooltip";
26
+ import * as i16 from "@ngx-translate/core";
27
+ import * as i17 from "../pipes/truncate.pipe";
28
+ export class AppTocContentCardV2Component {
29
+ constructor(events, dialog, renderer, certificateService, appTocSvc, contentLangSvc, resourceDownloadHelperSvc, configSvc, snackBar) {
30
+ this.events = events;
31
+ this.dialog = dialog;
32
+ this.renderer = renderer;
33
+ this.certificateService = certificateService;
34
+ this.appTocSvc = appTocSvc;
35
+ this.contentLangSvc = contentLangSvc;
36
+ this.resourceDownloadHelperSvc = resourceDownloadHelperSvc;
37
+ this.configSvc = configSvc;
38
+ this.snackBar = snackBar;
39
+ this.content = null;
40
+ this.expandAll = false;
41
+ this.forPreview = false;
42
+ this.componentName = 'toc';
43
+ this.expandActive = true;
44
+ this.hierarchyMapData = {};
45
+ this.batchData = null;
46
+ this.isPreAssessment = false;
47
+ this.baseContentReadData = null;
48
+ this.mlCourse = null;
49
+ this.parentMilestoneLocked = false; // Passed from parent when inside a locked milestone
50
+ this.hasContentStructure = false;
51
+ this.downloadCertificateLoading = false;
52
+ this.enumContentTypes = NsContent.EDisplayContentTypes;
53
+ this.contentStructure = {
54
+ assessment: 0,
55
+ finalTest: 0,
56
+ course: 0,
57
+ handsOn: 0,
58
+ interactiveVideo: 0,
59
+ learningModule: 0,
60
+ other: 0,
61
+ pdf: 0,
62
+ survey: 0,
63
+ podcast: 0,
64
+ practiceTest: 0,
65
+ quiz: 0,
66
+ video: 0,
67
+ webModule: 0,
68
+ webPage: 0,
69
+ youtube: 0,
70
+ interactivecontent: 0,
71
+ offlineSession: 0,
72
+ };
73
+ this.defaultThumbnail = '';
74
+ this.viewChildren = false;
75
+ this.primaryCategory = NsContent.EPrimaryCategory;
76
+ this.pageScrollSubscription = null;
77
+ this.hashmapUpdatedSubscription = null;
78
+ this.achievementLoading = false;
79
+ // Cached computed properties for performance optimization
80
+ this._cachedIsCollection = false;
81
+ this._cachedIsModule = false;
82
+ this._cachedIsResource = false;
83
+ this._cachedIsMilestone = false;
84
+ this._cachedIsMilestoneLocked = false;
85
+ this._cachedIsParentMilestoneLocked = false;
86
+ this._cachedIsContentUnlocked = true;
87
+ this._cachedCheckForCuratedProgram = false;
88
+ this._cachedIsMilestoneAssessment = false;
89
+ this._cachedIsMilestoneAssessmentLocked = false;
90
+ this._cachedResourceLink = { url: '', queryParams: {} };
91
+ this._cacheInitialized = false;
92
+ }
93
+ ngOnInit() {
94
+ this.evaluateImmediateChildrenStructure();
95
+ this.initializeComputedProperties();
96
+ // this.route.data.subscribe(data => {
97
+ // this.defaultThumbnail = data.configData.data.logos.defaultContent
98
+ // }
99
+ // )
100
+ this.resourceScroll();
101
+ // Subscribe to hashmap updates to recompute cached properties when progress changes
102
+ this.hashmapUpdatedSubscription = this.appTocSvc.hashmapUpdated$.subscribe((update) => {
103
+ if (update && update.hashmap) {
104
+ console.log('🔄 Hashmap updated, recomputing cached properties for:', this.content?.identifier);
105
+ // IMPORTANT: Update hierarchyMapData with the latest hashmap from the service
106
+ // This ensures the component uses the updated data, not the stale @Input reference
107
+ this.hierarchyMapData = update.hashmap;
108
+ this.computeAllCachedProperties();
109
+ }
110
+ });
111
+ }
112
+ /**
113
+ * Initialize all computed properties once to avoid expensive getter calculations
114
+ * on every change detection cycle
115
+ */
116
+ initializeComputedProperties() {
117
+ this.computeAllCachedProperties();
118
+ }
119
+ /**
120
+ * Compute all cached properties at once for performance optimization
121
+ */
122
+ computeAllCachedProperties() {
123
+ if (!this.content) {
124
+ this._cacheInitialized = false;
125
+ return;
126
+ }
127
+ const contentId = this.content.identifier;
128
+ const hashData = this.hierarchyMapData && this.hierarchyMapData[contentId];
129
+ // Use hashmap data if available for pre-computed values
130
+ if (hashData) {
131
+ this._cachedIsCollection = hashData.isCollection !== undefined ?
132
+ hashData.isCollection : this.content.mimeType === NsContent.EMimeTypes.COLLECTION;
133
+ this._cachedIsModule = hashData.isModule !== undefined ?
134
+ hashData.isModule : this.content.primaryCategory === NsContent.EPrimaryCategory.MODULE;
135
+ this._cachedIsResource = hashData.isResource !== undefined ?
136
+ hashData.isResource : this.computeIsResource();
137
+ this._cachedIsMilestone = hashData.isMilestone !== undefined ?
138
+ hashData.isMilestone : this.computeIsMilestone();
139
+ this._cachedIsMilestoneLocked = hashData.computedIsLocked !== undefined ?
140
+ hashData.computedIsLocked : this.computeIsMilestoneLocked();
141
+ this._cachedIsParentMilestoneLocked = hashData.isParentMilestoneLocked !== undefined ?
142
+ hashData.isParentMilestoneLocked : this.computeIsParentMilestoneLocked();
143
+ }
144
+ else {
145
+ // Fallback to direct computation if hashmap not available
146
+ this._cachedIsCollection = this.content.mimeType === NsContent.EMimeTypes.COLLECTION;
147
+ this._cachedIsModule = this.content.primaryCategory === NsContent.EPrimaryCategory.MODULE;
148
+ this._cachedIsResource = this.computeIsResource();
149
+ this._cachedIsMilestone = this.computeIsMilestone();
150
+ this._cachedIsMilestoneLocked = this.computeIsMilestoneLocked();
151
+ this._cachedIsParentMilestoneLocked = this.computeIsParentMilestoneLocked();
152
+ }
153
+ this._cachedCheckForCuratedProgram = this.computeCheckForCuratedProgram();
154
+ this._cachedIsContentUnlocked = this.computeIsContentUnlocked();
155
+ this._cachedIsMilestoneAssessment = this.computeIsMilestoneAssessment();
156
+ this._cachedIsMilestoneAssessmentLocked = this.computeIsMilestoneAssessmentLocked();
157
+ this._cachedResourceLink = this.computeResourceLink();
158
+ this._cacheInitialized = true;
159
+ }
160
+ computeIsResource() {
161
+ if (!this.content)
162
+ return false;
163
+ return (this.content.primaryCategory === NsContent.EPrimaryCategory.RESOURCE ||
164
+ this.content.primaryCategory === NsContent.EPrimaryCategory.PRACTICE_RESOURCE ||
165
+ this.content.primaryCategory === NsContent.EPrimaryCategory.FINAL_ASSESSMENT ||
166
+ this.content.primaryCategory === NsContent.EPrimaryCategory.COMP_ASSESSMENT);
167
+ }
168
+ computeIsMilestone() {
169
+ if (!this.content)
170
+ return false;
171
+ const primaryCat = this.content.primaryCategory;
172
+ const courseCat = this.content.courseCategory;
173
+ return primaryCat === 'Milestone' || courseCat === 'Milestone';
174
+ }
175
+ computeCheckForCuratedProgram() {
176
+ if (this.content && this.content.parent && this.hierarchyMapData && this.hierarchyMapData[this.content.parent]) {
177
+ const parentData = this.hierarchyMapData[this.content.parent];
178
+ return parentData && parentData.primaryCategory === NsContent.EPrimaryCategory.CURATED_PROGRAM &&
179
+ parentData.compatibilityLevel >= 5 &&
180
+ parentData.contextLockingType === NsContent.EContextLockingType.COURSE_ASSESSMENT_ONLY;
181
+ }
182
+ return false;
183
+ }
184
+ computeIsContentUnlocked() {
185
+ if (this._cachedCheckForCuratedProgram) {
186
+ if (this.content && this.content.parent && this.hierarchyMapData && this.hierarchyMapData[this.content.parent]) {
187
+ const parentData = this.hierarchyMapData[this.content.parent];
188
+ let completedLeafNodes = [];
189
+ parentData.leafNodes.forEach((_ele) => {
190
+ if (this.hierarchyMapData && this.hierarchyMapData[_ele]) {
191
+ const childData = this.hierarchyMapData[_ele];
192
+ if (childData && childData.completionStatus === 2) {
193
+ completedLeafNodes.push(childData);
194
+ }
195
+ }
196
+ });
197
+ return completedLeafNodes.length >= parentData.leafNodesCount - 1;
198
+ }
199
+ return false;
200
+ }
201
+ return true;
202
+ }
203
+ computeResourceLink() {
204
+ if (this.content) {
205
+ let mimeType = '';
206
+ if (this.content && this.content.courseCategory === 'Pre Enrolment Assessment' &&
207
+ this.content.mimeType === 'application/vnd.ekstep.content-collection') {
208
+ mimeType = 'application/vnd.sunbird.questionset';
209
+ this.content.mimeType = NsContent.EMimeTypes.FINAL_ASSESSMENT;
210
+ }
211
+ else {
212
+ mimeType = this.content.mimeType;
213
+ }
214
+ const selectedLanguage = this.mlCourse ? this.contentLangSvc.getSelectedLanguage(this.mlCourse) : undefined;
215
+ return viewerRouteGenerator(this.content.identifier, mimeType, this.baseContentReadData?.identifier || this.rootId, this.baseContentReadData?.contentType || this.rootContentType, this.forPreview, this.content.primaryCategory, this.batchId, this.content?.name || this.baseContentReadData?.name, (selectedLanguage ? selectedLanguage.langId : null), (selectedLanguage ? selectedLanguage.identifier : null));
216
+ }
217
+ return { url: '', queryParams: {} };
218
+ }
219
+ computeIsMilestoneLocked() {
220
+ // Only apply milestone locking for Learning Pathway content
221
+ if (!this.baseContentReadData || this.baseContentReadData.courseCategory !== 'Learning Pathway') {
222
+ return false;
223
+ }
224
+ if (!this.content) {
225
+ return false;
226
+ }
227
+ // Check if current content is a Milestone
228
+ if (!this._cachedIsMilestone && !this.computeIsMilestone()) {
229
+ return false;
230
+ }
231
+ // Check if hashmap has pre-computed locking status (preferred - computed by service)
232
+ const hashData = this.hierarchyMapData && this.hierarchyMapData[this.content.identifier];
233
+ console.log(`computeIsMilestoneLocked for ${this.content.identifier} (${this.content.name}):`, {
234
+ hashData,
235
+ computedIsLocked: hashData?.computedIsLocked,
236
+ contentIsLocked: this.content.isLocked
237
+ });
238
+ if (hashData && hashData.computedIsLocked !== undefined) {
239
+ return hashData.computedIsLocked;
240
+ }
241
+ // If milestone has isLocked flag explicitly set to false, it's unlocked
242
+ if (this.content.isLocked === false) {
243
+ return false;
244
+ }
245
+ // Fallback: All milestones are locked by default until computed otherwise
246
+ // This ensures proper locking until the hashmap is updated with progress
247
+ return true;
248
+ }
249
+ computeIsParentMilestoneLocked() {
250
+ if (this.parentMilestoneLocked) {
251
+ return true;
252
+ }
253
+ if (!this.baseContentReadData || this.baseContentReadData.courseCategory !== 'Learning Pathway') {
254
+ return false;
255
+ }
256
+ if (!this.content || !this.hierarchyMapData) {
257
+ return false;
258
+ }
259
+ // Check hashmap for pre-computed value
260
+ const hashData = this.hierarchyMapData[this.content.identifier];
261
+ if (hashData && hashData.isParentMilestoneLocked !== undefined) {
262
+ return hashData.isParentMilestoneLocked;
263
+ }
264
+ // Traverse up the hierarchy to find if any ancestor is a locked Milestone
265
+ let currentParentId = this.content.parent;
266
+ const maxDepth = 5;
267
+ let depth = 0;
268
+ while (currentParentId && depth < maxDepth) {
269
+ const parentData = this.hierarchyMapData[currentParentId];
270
+ if (parentData) {
271
+ if ((parentData.isMilestone || parentData.primaryCategory === 'Milestone' || parentData.courseCategory === 'Milestone') &&
272
+ (parentData.computedIsLocked || parentData.isLocked)) {
273
+ return true;
274
+ }
275
+ currentParentId = parentData.parent;
276
+ }
277
+ else {
278
+ break;
279
+ }
280
+ depth++;
281
+ }
282
+ return false;
283
+ }
284
+ /**
285
+ * Check if current content is a MILESTONE assessment (DIRECT child of a Milestone)
286
+ * IMPORTANT: This should NOT return true for course assessments inside courses within milestones
287
+ * Only assessments that are direct children of milestones should be locked by milestone logic
288
+ */
289
+ computeIsMilestoneAssessment() {
290
+ if (!this.baseContentReadData || this.baseContentReadData.courseCategory !== 'Learning Pathway') {
291
+ return false;
292
+ }
293
+ if (!this.content || !this.hierarchyMapData) {
294
+ return false;
295
+ }
296
+ // Check if this is an assessment type
297
+ // Note: FINAL_ASSESSMENT maps to 'Course Assessment' in the enum, not 'Final Assessment'
298
+ const isAssessment = this.content.primaryCategory === 'Course Assessment' ||
299
+ this.content.primaryCategory === 'Standalone Assessment' ||
300
+ this.content.mimeType === 'application/vnd.sunbird.questionset' ||
301
+ this.content.mimeType === 'application/quiz';
302
+ if (!isAssessment) {
303
+ return false;
304
+ }
305
+ // IMPORTANT: Only return true if the DIRECT parent is a milestone
306
+ // Assessments inside courses (grandchildren of milestones) should NOT be locked by milestone logic
307
+ // They follow their own course's locking rules
308
+ // Get the parent from hashmap (which we fixed to track correct parent-child relationships)
309
+ // or fallback to content.parent if hashmap entry doesn't exist
310
+ const contentHashData = this.hierarchyMapData[this.content.identifier];
311
+ const parentId = contentHashData?.parent || this.content.parent;
312
+ console.log(`🔍 computeIsMilestoneAssessment for "${this.content.name}" (${this.content.identifier}):`, {
313
+ contentId: this.content.identifier,
314
+ primaryCategory: this.content.primaryCategory,
315
+ mimeType: this.content.mimeType,
316
+ contentParent: this.content.parent,
317
+ hashmapParent: contentHashData?.parent,
318
+ resolvedParentId: parentId,
319
+ hasParentData: !!this.hierarchyMapData[parentId]
320
+ });
321
+ if (parentId && this.hierarchyMapData[parentId]) {
322
+ const parentData = this.hierarchyMapData[parentId];
323
+ console.log(` Parent details:`, {
324
+ parentId: parentId,
325
+ parentName: parentData?.name,
326
+ parentPrimaryCategory: parentData?.primaryCategory,
327
+ parentIsMilestone: parentData?.isMilestone,
328
+ parentCourseCategory: parentData?.courseCategory,
329
+ });
330
+ // Check if DIRECT parent is a milestone - ONLY this case
331
+ const isParentMilestone = parentData.isMilestone ||
332
+ parentData.primaryCategory === 'Milestone' ||
333
+ parentData.courseCategory === 'Milestone';
334
+ if (isParentMilestone) {
335
+ console.log(` ✅ Result: IS a milestone assessment (direct child of milestone)`);
336
+ return true;
337
+ }
338
+ console.log(` ❌ Result: NOT a milestone assessment (parent is ${parentData.primaryCategory}, not a Milestone)`);
339
+ // DO NOT check grandparent - course assessments inside courses within milestones
340
+ // should NOT be treated as milestone assessments
341
+ return false;
342
+ }
343
+ else {
344
+ console.log(` ⚠️ No parent data found for ${parentId}`);
345
+ }
346
+ return false;
347
+ }
348
+ /**
349
+ * Check if milestone assessment should be locked
350
+ * Assessment is locked if:
351
+ * 1. It's an assessment that is a DIRECT child of a milestone
352
+ * 2. The parent milestone is unlocked (otherwise handled by parent milestone lock)
353
+ * 3. NOT all mandatory courses in the same milestone are completed
354
+ */
355
+ computeIsMilestoneAssessmentLocked() {
356
+ // CRITICAL: Only apply milestone assessment locking for Learning Pathway content
357
+ // Regular courses should NEVER have their assessments locked by milestone logic
358
+ if (!this.baseContentReadData || this.baseContentReadData.courseCategory !== 'Learning Pathway') {
359
+ return false;
360
+ }
361
+ // Only apply to assessments that are DIRECT children of milestones
362
+ const isMilestoneAssessment = this._cachedIsMilestoneAssessment || this.computeIsMilestoneAssessment();
363
+ console.log(`🔒 computeIsMilestoneAssessmentLocked for "${this.content?.name}":`, {
364
+ isMilestoneAssessment,
365
+ _cachedIsMilestoneAssessment: this._cachedIsMilestoneAssessment,
366
+ courseCategory: this.baseContentReadData?.courseCategory,
367
+ });
368
+ if (!isMilestoneAssessment) {
369
+ console.log(`🔓 "${this.content?.name}" NOT locked - not a milestone assessment`);
370
+ return false;
371
+ }
372
+ // Check if hashmap has pre-computed assessment locking status
373
+ const hashData = this.hierarchyMapData && this.hierarchyMapData[this.content?.identifier || ''];
374
+ if (hashData && hashData.isAssessmentLocked !== undefined) {
375
+ return hashData.isAssessmentLocked;
376
+ }
377
+ // If already completed, don't lock
378
+ if (this.content && (this.content.completionStatus === 2 ||
379
+ (this.content.completionPercentage && this.content.completionPercentage >= 100))) {
380
+ return false;
381
+ }
382
+ // For milestone assessments, the parent IS the milestone (verified by computeIsMilestoneAssessment)
383
+ // Use hashmap's parent which has correct parent-child relationships
384
+ const contentHashData = this.hierarchyMapData && this.hierarchyMapData[this.content?.identifier || ''];
385
+ const milestoneId = contentHashData?.parent || this.content?.parent;
386
+ if (!milestoneId || !this.hierarchyMapData) {
387
+ return false;
388
+ }
389
+ const milestone = this.hierarchyMapData[milestoneId];
390
+ if (!milestone) {
391
+ return false;
392
+ }
393
+ // If the parent milestone itself is locked, don't add additional locking
394
+ // (the parent lock will handle it)
395
+ if (milestone.computedIsLocked || milestone.isLocked) {
396
+ return false;
397
+ }
398
+ // Check if all mandatory COURSES in the milestone are completed
399
+ // Note: Only checking courses that are direct children of the milestone
400
+ let mandatoryCount = 0;
401
+ let completedMandatoryCount = 0;
402
+ for (const key of Object.keys(this.hierarchyMapData)) {
403
+ const item = this.hierarchyMapData[key];
404
+ // Only check items that are direct children of this milestone
405
+ if (item.parent !== milestoneId)
406
+ continue;
407
+ // Only count courses (not assessments, not other types)
408
+ if (item.primaryCategory !== 'Course' && !item.isCollection)
409
+ continue;
410
+ // Skip if this is an assessment
411
+ const isItemAssessment = item.primaryCategory === 'Course Assessment' ||
412
+ item.primaryCategory === 'Final Assessment' ||
413
+ item.primaryCategory === 'Standalone Assessment' ||
414
+ item.mimeType === 'application/vnd.sunbird.questionset';
415
+ if (isItemAssessment)
416
+ continue;
417
+ // By default, courses are mandatory unless explicitly marked as optional
418
+ if (item.isMandatory !== false) {
419
+ mandatoryCount++;
420
+ const isCompleted = item.completionStatus === 2 || item.status === 2 ||
421
+ item.completionPercentage >= 100 || item.progress >= 100;
422
+ if (isCompleted) {
423
+ completedMandatoryCount++;
424
+ }
425
+ }
426
+ }
427
+ // If there are no mandatory courses, assessment is unlocked
428
+ if (mandatoryCount === 0) {
429
+ return false;
430
+ }
431
+ // Lock assessment if not all mandatory courses are completed
432
+ const allMandatoryComplete = completedMandatoryCount >= mandatoryCount;
433
+ return !allMandatoryComplete;
434
+ }
435
+ // FOR RIGHT SIDE RESOURCE SCROLL ON TOC PAGE
436
+ resourceScroll() {
437
+ this.pageScrollSubscription = this.appTocSvc.updatePageScroll.subscribe((value) => {
438
+ if (value) {
439
+ setTimeout(() => {
440
+ this.scrollView();
441
+ }, 700);
442
+ }
443
+ });
444
+ }
445
+ // TO UPDATE RESOURCE BEHAVOUR SUBJECT FOR RESOURCE SCROLL
446
+ changeResource() {
447
+ this.appTocSvc.getPageScroll.next(true);
448
+ }
449
+ ngOnChanges(changes) {
450
+ let shouldRecomputeCache = false;
451
+ for (const property in changes) {
452
+ if (property === 'expandAll') {
453
+ this.viewChildren = this.expandAll;
454
+ }
455
+ if (property === 'pathSet' && changes['pathSet']) {
456
+ let currentValue = changes['pathSet'].currentValue;
457
+ let previousValue = changes['pathSet'].previousValue;
458
+ if (currentValue && previousValue) {
459
+ const eqSet = (xs, ys) => xs.size === ys.size &&
460
+ [...xs].every((x) => ys.has(x));
461
+ if (!eqSet(previousValue, currentValue)) { }
462
+ }
463
+ // if(previousValue === undefined){
464
+ // setTimeout(()=>{
465
+ // },700)
466
+ // }
467
+ }
468
+ // this.appTocSvc.getPageScroll.next(true)
469
+ if (property === 'hierarchyMapData') {
470
+ if (_.isEmpty(changes['hierarchyMapData'].currentValue)) {
471
+ // this.loadingOverallPRogress = true
472
+ }
473
+ else {
474
+ if (this.content) {
475
+ this.updateChildParentMap(this.content.identifier);
476
+ }
477
+ shouldRecomputeCache = true;
478
+ }
479
+ }
480
+ // Recompute cache when critical inputs change
481
+ if (property === 'content' || property === 'baseContentReadData' ||
482
+ property === 'batchId' || property === 'forPreview' ||
483
+ property === 'parentMilestoneLocked' || property === 'mlCourse') {
484
+ shouldRecomputeCache = true;
485
+ }
486
+ }
487
+ // Recompute all cached properties if needed
488
+ if (shouldRecomputeCache) {
489
+ this.computeAllCachedProperties();
490
+ }
491
+ // console.log('pre assessment content---', this.content)
492
+ // console.log('this.hierarchyMapData---', this.hierarchyMapData)
493
+ }
494
+ check(content) {
495
+ if (this.expandActive) {
496
+ content.viewChildren = this.pathSet && this.pathSet.has(content.identifier) || content.viewChildren;
497
+ }
498
+ return content.viewChildren;
499
+ }
500
+ get isCollection() {
501
+ if (this._cacheInitialized) {
502
+ return this._cachedIsCollection;
503
+ }
504
+ if (this.content) {
505
+ return this.content.mimeType === NsContent.EMimeTypes.COLLECTION;
506
+ }
507
+ return false;
508
+ }
509
+ get isModule() {
510
+ if (this._cacheInitialized) {
511
+ return this._cachedIsModule;
512
+ }
513
+ if (this.content) {
514
+ return this.content.primaryCategory === NsContent.EPrimaryCategory.MODULE;
515
+ }
516
+ return false;
517
+ }
518
+ checkModule(content) {
519
+ if (content) {
520
+ return content.primaryCategory === NsContent.EPrimaryCategory.MODULE;
521
+ }
522
+ return false;
523
+ }
524
+ checkIsModule(content) {
525
+ if (content) {
526
+ return content.primaryCategory === NsContent.EPrimaryCategory.MODULE;
527
+ }
528
+ return false;
529
+ }
530
+ get isBatchInProgess() {
531
+ if (this.batchData && (this.batchData.content && this.batchData.content.length) && this.batchData.enrolled) {
532
+ const batchData = this.batchData.content[0];
533
+ if (batchData && batchData.endDate) {
534
+ const now = moment().format('YYYY-MM-DD');
535
+ const startDate = moment(batchData.startDate).format('YYYY-MM-DD');
536
+ const endDate = batchData.endDate ? moment(batchData.endDate).format('YYYY-MM-DD') : now;
537
+ return (
538
+ // batch.status &&
539
+ moment(startDate).isSameOrBefore(now)
540
+ && moment(endDate).isSameOrAfter(now));
541
+ }
542
+ return true;
543
+ }
544
+ return false;
545
+ }
546
+ get isResource() {
547
+ if (this._cacheInitialized) {
548
+ return this._cachedIsResource;
549
+ }
550
+ return this.computeIsResource();
551
+ }
552
+ get resourceLink() {
553
+ if (this._cacheInitialized) {
554
+ return this._cachedResourceLink;
555
+ }
556
+ return this.computeResourceLink();
557
+ }
558
+ progressColor() {
559
+ // if (this.currentProgress <= 30) {
560
+ // return '#D13924'
561
+ // } if (this.currentProgress > 30 && this.currentProgress <= 70) {
562
+ // return '#E99E38'
563
+ // }
564
+ // if (this.currentProgress > 70 && this.currentProgress <= 100) {
565
+ // return '#1D8923'
566
+ // }
567
+ return '#1D8923';
568
+ }
569
+ progressColor2() {
570
+ return '#f27d00';
571
+ }
572
+ evaluateImmediateChildrenStructure() {
573
+ if (this.content && this.content.children && this.content.children.length) {
574
+ this.content.children.forEach((child) => {
575
+ if (child.primaryCategory === NsContent.EPrimaryCategory.COURSE) {
576
+ this.contentStructure.course += 1;
577
+ }
578
+ else if (child.primaryCategory === NsContent.EPrimaryCategory.KNOWLEDGE_ARTIFACT) {
579
+ this.contentStructure.other += 1;
580
+ }
581
+ else if (child.primaryCategory === NsContent.EPrimaryCategory.MODULE) {
582
+ this.contentStructure.learningModule += 1;
583
+ }
584
+ else if (child.primaryCategory === NsContent.EPrimaryCategory.OFFLINE_SESSION) {
585
+ this.contentStructure.offlineSession += 1;
586
+ }
587
+ else if (child.primaryCategory === NsContent.EPrimaryCategory.RESOURCE) {
588
+ switch (child.mimeType) {
589
+ case NsContent.EMimeTypes.HANDS_ON:
590
+ this.contentStructure.handsOn += 1;
591
+ break;
592
+ case NsContent.EMimeTypes.MP3:
593
+ this.contentStructure.podcast += 1;
594
+ break;
595
+ case NsContent.EMimeTypes.MP4:
596
+ case NsContent.EMimeTypes.M3U8:
597
+ this.contentStructure.video += 1;
598
+ break;
599
+ case NsContent.EMimeTypes.INTERACTION:
600
+ this.contentStructure.interactiveVideo += 1;
601
+ break;
602
+ case NsContent.EMimeTypes.PDF:
603
+ this.contentStructure.pdf += 1;
604
+ break;
605
+ case NsContent.EMimeTypes.OFFLINE_SESSION:
606
+ this.contentStructure.offlineSession += 1;
607
+ break;
608
+ case NsContent.EMimeTypes.SURVEY:
609
+ this.contentStructure.survey += 1;
610
+ break;
611
+ case NsContent.EMimeTypes.HTML:
612
+ this.contentStructure.webPage += 1;
613
+ break;
614
+ case NsContent.EMimeTypes.QUIZ:
615
+ if (child.resourceType === 'Assessment') {
616
+ this.contentStructure.assessment += 1;
617
+ }
618
+ else {
619
+ this.contentStructure.quiz += 1;
620
+ }
621
+ break;
622
+ case NsContent.EMimeTypes.PRACTICE_RESOURCE:
623
+ // case NsContent.EMimeTypes.FINAL_ASSESSMENT:
624
+ // case NsContent.EMimeTypes.PRACTICE_RESOURCE:
625
+ this.contentStructure.practiceTest += 1;
626
+ break;
627
+ case NsContent.EMimeTypes.WEB_MODULE:
628
+ this.contentStructure.webModule += 1;
629
+ break;
630
+ case NsContent.EMimeTypes.YOUTUBE:
631
+ this.contentStructure.youtube += 1;
632
+ break;
633
+ default:
634
+ this.contentStructure.other += 1;
635
+ break;
636
+ }
637
+ }
638
+ });
639
+ }
640
+ for (const key in this.contentStructure) {
641
+ if (this.contentStructure[key] > 0) {
642
+ this.hasContentStructure = true;
643
+ }
644
+ }
645
+ }
646
+ get contextPath() {
647
+ return {
648
+ contextId: this.rootId,
649
+ contextPath: this.rootContentType,
650
+ batchId: this.batchId,
651
+ };
652
+ }
653
+ contentTrackBy(_index, content) {
654
+ if (!content) {
655
+ return null;
656
+ }
657
+ return content.identifier;
658
+ }
659
+ raiseTelemetry() {
660
+ // if (this.forPreview) { return }
661
+ if (this.content) {
662
+ this.events.raiseInteractTelemetry({
663
+ type: 'click',
664
+ subType: `card-tocContentCard`,
665
+ // id: this.content.identifier || '',
666
+ }, {
667
+ // contentId: this.content.identifier || '',
668
+ // contentType: this.content.primaryCategory,
669
+ id: this.content.identifier || '',
670
+ type: this.content.primaryCategory,
671
+ rollup: {
672
+ l1: this.rootId || '',
673
+ },
674
+ ver: `${this.content.version}${''}`,
675
+ }, {
676
+ pageIdExt: `${_.camelCase(this.content.primaryCategory)}-card`,
677
+ module: _.camelCase(this.content.primaryCategory),
678
+ });
679
+ }
680
+ }
681
+ get isAllowed() {
682
+ if (this.content) {
683
+ return !(NsContent.UN_SUPPORTED_DATA_TYPES_FOR_NON_BATCH_USERS.indexOf(this.content.mimeType) >= 0);
684
+ }
685
+ return false;
686
+ }
687
+ get isEnabled() {
688
+ return true;
689
+ }
690
+ get isEnrolled() {
691
+ // Check both batchId and batchData.enrolled to support Learning Pathways
692
+ // where batchId might not be directly set but user is enrolled in courses within the pathway
693
+ return this.batchId ? true : (this.batchData?.enrolled || false);
694
+ }
695
+ updateChildParentMap(identifier) {
696
+ if (this.hierarchyMapData && this.hierarchyMapData[identifier]) {
697
+ let localContentData = this.hierarchyMapData[identifier];
698
+ if (!(localContentData.primaryCategory === NsContent.EPrimaryCategory.RESOURCE
699
+ || localContentData.primaryCategory === NsContent.EPrimaryCategory.PRACTICE_RESOURCE
700
+ || localContentData.primaryCategory === NsContent.EPrimaryCategory.FINAL_ASSESSMENT
701
+ || localContentData.primaryCategory === NsContent.EPrimaryCategory.COMP_ASSESSMENT)) {
702
+ // real percent logic
703
+ // const total = localContentData.leafNodes.reduce((sum: number, childId: string) => {
704
+ // return sum + Number(this.hierarchyMapData[childId].completionPercentage || 0)
705
+ // }, 0)
706
+ // console.log('total ', total)
707
+ // if(total > 0) {
708
+ // this.hierarchyMapData[identifier]['completionPercentage'] = total / _.toInteger(_.get(this.hierarchyMapData[identifier], 'leafNodesCount'))
709
+ // }
710
+ if (localContentData.primaryCategory === NsContent.EPrimaryCategory.MODULE) {
711
+ this.hierarchyMapData[identifier]['duration'] = this.hierarchyMapData[identifier].leafNodes.reduce((sum, childID) => {
712
+ if (this.hierarchyMapData && this.hierarchyMapData[childID]) {
713
+ return sum + Number(this.hierarchyMapData[childID].duration || this.hierarchyMapData[childID].expectedDuration || 0);
714
+ }
715
+ }, 0);
716
+ }
717
+ // tslint:disable
718
+ const completedItems = _.filter(this.hierarchyMapData[identifier].leafNodes, r => (this.hierarchyMapData[r] && (this.hierarchyMapData[r].completionStatus === 2 || this.hierarchyMapData[r].completionPercentage === 100)));
719
+ const totalCount = _.toInteger(_.get(this.hierarchyMapData[identifier], 'leafNodesCount')) || 1;
720
+ this.hierarchyMapData[identifier]['completionPercentage'] = Number(((completedItems.length / totalCount) * 100).toFixed());
721
+ this.hierarchyMapData[identifier]['completionStatus'] = (this.hierarchyMapData[identifier].completionPercentage >= 100) ? 2 : 1;
722
+ }
723
+ return this.hierarchyMapData[identifier];
724
+ }
725
+ return '';
726
+ }
727
+ getCompletionPercentage(identifier) {
728
+ // console.log('getCompletionPercentage', identifier)
729
+ // console.log('this.hierarchyMapData[identifier] : ', this.hierarchyMapData[identifier])
730
+ // const item = this.updateChildParentMap(identifier)
731
+ let percent = this.hierarchyMapData && this.hierarchyMapData[identifier] && this.hierarchyMapData[identifier].completionPercentage || 0;
732
+ return this.roundIfDecimal(percent);
733
+ }
734
+ roundIfDecimal(value) {
735
+ if (!Number.isInteger(value)) {
736
+ return parseFloat(value.toFixed(2));
737
+ }
738
+ return value;
739
+ }
740
+ getCompletionStatus(identifier) {
741
+ // console.log('getCompletionStatus')
742
+ // const item = this.updateChildParentMap(identifier)
743
+ return this.hierarchyMapData && this.hierarchyMapData[identifier] && this.hierarchyMapData[identifier].completionStatus;
744
+ }
745
+ openCertificateDialog(certData) {
746
+ const cet = certData;
747
+ this.dialog.open(CertificateDialogComponent, {
748
+ // height: '400px',
749
+ width: '1300px',
750
+ data: { cet },
751
+ // panelClass: 'custom-dialog-container',
752
+ });
753
+ }
754
+ scrollView() {
755
+ try {
756
+ let errorField = this.renderer.selectRootElement('.resource-container .resource-active');
757
+ if (errorField) {
758
+ errorField.scrollIntoView({ behavior: "smooth", block: "start", inline: "nearest" });
759
+ }
760
+ if (this.componentName === 'toc') {
761
+ if (errorField) {
762
+ const rect = errorField.getBoundingClientRect();
763
+ if (rect.top - 420 > 0) {
764
+ window.scroll(420, rect.top - 148);
765
+ }
766
+ }
767
+ }
768
+ setTimeout(() => {
769
+ this.appTocSvc.getPageScroll.next(false);
770
+ }, 700);
771
+ // else {
772
+ // errorField.scrollIntoView({ behavior: "smooth", block: "start", inline: "nearest" });
773
+ // const rect = errorField.getBoundingClientRect();
774
+ // errorField.scroll(0,rect.top-56)
775
+ // }
776
+ }
777
+ catch (err) {
778
+ }
779
+ }
780
+ downloadCertificate(certificateData) {
781
+ this.events.raiseInteractTelemetry({
782
+ type: WsEvents.EnumInteractTypes.CLICK,
783
+ id: 'view-certificate',
784
+ subType: WsEvents.EnumInteractSubTypes.CERTIFICATE,
785
+ }, {
786
+ id: certificateData,
787
+ type: WsEvents.EnumInteractSubTypes.CERTIFICATE,
788
+ });
789
+ if (certificateData) {
790
+ this.downloadCertificateLoading = true;
791
+ let certData = certificateData;
792
+ this.certificateService.downloadCertificate_v2(certData).subscribe((res) => {
793
+ this.downloadCertificateLoading = false;
794
+ const cet = res.result.printUri;
795
+ this.dialog.open(CertificateDialogComponent, {
796
+ width: '1300px',
797
+ data: { cet, certId: certData.identifier },
798
+ });
799
+ });
800
+ }
801
+ else {
802
+ this.downloadCertificateLoading = false;
803
+ }
804
+ }
805
+ ngOnDestroy() {
806
+ if (this.hashmapUpdatedSubscription) {
807
+ this.hashmapUpdatedSubscription.unsubscribe();
808
+ }
809
+ if (this.pageScrollSubscription) {
810
+ this.pageScrollSubscription.unsubscribe();
811
+ }
812
+ }
813
+ get checkForCuratedProgram() {
814
+ if (this._cacheInitialized) {
815
+ return this._cachedCheckForCuratedProgram;
816
+ }
817
+ return this.computeCheckForCuratedProgram();
818
+ }
819
+ get isContentUnlocked() {
820
+ if (this._cacheInitialized) {
821
+ return this._cachedIsContentUnlocked;
822
+ }
823
+ return this.computeIsContentUnlocked();
824
+ }
825
+ get isParentMilestoneLocked() {
826
+ if (this._cacheInitialized) {
827
+ return this._cachedIsParentMilestoneLocked;
828
+ }
829
+ return this.computeIsParentMilestoneLocked();
830
+ }
831
+ get isMilestoneLocked() {
832
+ if (this._cacheInitialized) {
833
+ return this._cachedIsMilestoneLocked;
834
+ }
835
+ return this.computeIsMilestoneLocked();
836
+ }
837
+ get isMilestoneAssessment() {
838
+ if (this._cacheInitialized) {
839
+ return this._cachedIsMilestoneAssessment;
840
+ }
841
+ return this.computeIsMilestoneAssessment();
842
+ }
843
+ get isMilestoneAssessmentLocked() {
844
+ if (this._cacheInitialized) {
845
+ return this._cachedIsMilestoneAssessmentLocked;
846
+ }
847
+ return this.computeIsMilestoneAssessmentLocked();
848
+ }
849
+ /**
850
+ * Check if a milestone's mandatory courses and assessment are completed.
851
+ * Looks at the content hierarchy to find children of the milestone.
852
+ */
853
+ checkMilestoneContentCompletion(milestoneId) {
854
+ if (!this.baseContentReadData || !this.baseContentReadData.children || !this.hierarchyMapData) {
855
+ // Fallback: Try to find assessment completion in hashmap for this milestone
856
+ return this.checkMilestoneAssessmentCompletion(milestoneId);
857
+ }
858
+ // Find the milestone in the content hierarchy
859
+ const milestoneContent = this.findContentInHierarchy(this.baseContentReadData, milestoneId);
860
+ if (!milestoneContent || !milestoneContent.children) {
861
+ return this.checkMilestoneAssessmentCompletion(milestoneId);
862
+ }
863
+ // Check all mandatory courses and assessments
864
+ let allMandatoryComplete = true;
865
+ let hasAssessment = false;
866
+ let assessmentComplete = false;
867
+ milestoneContent.children.forEach((child) => {
868
+ const childData = this.hierarchyMapData[child.identifier];
869
+ const isAssessment = child.primaryCategory === 'Course Assessment' ||
870
+ child.courseCategory === 'Course Assessment' ||
871
+ child.primaryCategory === 'Final Assessment';
872
+ const isMandatory = child.mandatory === true || child.optionalReading !== true;
873
+ if (isAssessment) {
874
+ hasAssessment = true;
875
+ if (childData && (childData.completionStatus === 2 || childData.completionPercentage >= 100)) {
876
+ assessmentComplete = true;
877
+ }
878
+ }
879
+ else if (isMandatory) {
880
+ // Check if mandatory content is completed
881
+ if (!childData || (childData.completionStatus !== 2 && childData.completionPercentage < 100)) {
882
+ allMandatoryComplete = false;
883
+ }
884
+ }
885
+ });
886
+ console.log('Milestone content check:', { allMandatoryComplete, hasAssessment, assessmentComplete });
887
+ // Milestone is complete if assessment is complete (mandatory courses optional based on requirements)
888
+ return hasAssessment ? assessmentComplete : allMandatoryComplete;
889
+ }
890
+ /**
891
+ * Fallback: Check if enough assessments are completed to unlock this milestone.
892
+ * For milestone at index N, we need at least N completed assessments.
893
+ * E.g., For M2 (index 1), we need 1 completed assessment (M1's assessment)
894
+ * For M3 (index 2), we need 2 completed assessments (M1's and M2's)
895
+ */
896
+ checkMilestoneAssessmentCompletion(milestoneId) {
897
+ if (!this.hierarchyMapData) {
898
+ return false;
899
+ }
900
+ // Extract milestone number from ID (M1 -> 1, M2 -> 2, etc.)
901
+ const milestoneNum = parseInt(milestoneId.replace(/\D/g, '')) || 0;
902
+ const requiredCompletedAssessments = milestoneNum - 1; // For M2, need 1; for M3, need 2
903
+ console.log(`Milestone ${milestoneId} (num: ${milestoneNum}) requires ${requiredCompletedAssessments} completed assessments`);
904
+ if (requiredCompletedAssessments <= 0) {
905
+ return true; // First milestone, no requirements
906
+ }
907
+ // Count completed Course Assessments that are INSIDE milestones (have a parent)
908
+ // Exclude pre-enrollment assessments at the root level (no parent or parent is Learning Pathway)
909
+ let completedMilestoneAssessmentCount = 0;
910
+ const learningPathwayId = this.baseContentReadData?.identifier;
911
+ for (const key of Object.keys(this.hierarchyMapData)) {
912
+ const item = this.hierarchyMapData[key];
913
+ // Check if it's a completed Course Assessment
914
+ if ((item.primaryCategory === 'Course Assessment' || item.courseCategory === 'Course Assessment') &&
915
+ (item.completionStatus === 2 || item.completionPercentage >= 100)) {
916
+ // Check if this assessment has a parent (meaning it's inside a course/milestone, not at root level)
917
+ // Also exclude if parent is the Learning Pathway itself (pre-enrollment assessment)
918
+ const hasParent = item.parent && item.parent !== learningPathwayId;
919
+ if (hasParent) {
920
+ completedMilestoneAssessmentCount++;
921
+ console.log(`Found completed MILESTONE assessment: ${key}`, item);
922
+ }
923
+ else {
924
+ console.log(`Skipping root-level/pre-enrollment assessment: ${key}`);
925
+ }
926
+ }
927
+ }
928
+ console.log(`Total completed MILESTONE assessments: ${completedMilestoneAssessmentCount}, Required: ${requiredCompletedAssessments}`);
929
+ // If we have enough completed milestone assessments, unlock this milestone
930
+ return completedMilestoneAssessmentCount >= requiredCompletedAssessments;
931
+ }
932
+ findContentInHierarchy(content, identifier) {
933
+ if (!content)
934
+ return null;
935
+ if (content.identifier === identifier)
936
+ return content;
937
+ if (content.children) {
938
+ for (const child of content.children) {
939
+ const found = this.findContentInHierarchy(child, identifier);
940
+ if (found)
941
+ return found;
942
+ }
943
+ }
944
+ return null;
945
+ }
946
+ get computedQueryParams() {
947
+ if (this.isAllowed && !this.forPreview && this.isEnabled) {
948
+ return {
949
+ ...this.resourceLink.queryParams,
950
+ preAssessment: 'true'
951
+ };
952
+ }
953
+ return null;
954
+ }
955
+ get isMilestone() {
956
+ if (this._cacheInitialized) {
957
+ return this._cachedIsMilestone;
958
+ }
959
+ return this.computeIsMilestone();
960
+ }
961
+ getMilestoneCompletedCount() {
962
+ if (!this.content || !this.hierarchyMapData) {
963
+ return 0;
964
+ }
965
+ const milestoneData = this.hierarchyMapData[this.content.identifier];
966
+ if (!milestoneData || !milestoneData.leafNodes) {
967
+ return 0;
968
+ }
969
+ let completedCount = 0;
970
+ milestoneData.leafNodes.forEach((leafId) => {
971
+ const leafData = this.hierarchyMapData[leafId];
972
+ if (leafData && leafData.completionStatus === 2) {
973
+ completedCount++;
974
+ }
975
+ });
976
+ return completedCount;
977
+ }
978
+ /**
979
+ * Get unlock criteria message for locked milestones
980
+ */
981
+ getMilestoneUnlockMessage() {
982
+ if (!this.content || !this.hierarchyMapData) {
983
+ return '';
984
+ }
985
+ const milestoneData = this.hierarchyMapData[this.content.identifier];
986
+ if (!milestoneData) {
987
+ return '';
988
+ }
989
+ // Check if hashmap has pre-computed unlock message
990
+ if (milestoneData.unlockMessage) {
991
+ return milestoneData.unlockMessage;
992
+ }
993
+ const milestoneIndex = milestoneData.milestoneIndex;
994
+ // Milestone 1 requires pre-assessment completion
995
+ if (milestoneIndex === 0) {
996
+ return 'Complete the preliminary assessment to unlock this milestone';
997
+ }
998
+ // Other milestones require previous milestone completion
999
+ return `Complete all mandatory content and assessment in Milestone ${milestoneIndex} to unlock this milestone`;
1000
+ }
1001
+ /**
1002
+ * Get lock message for content inside locked milestones
1003
+ */
1004
+ getParentMilestoneLockMessage() {
1005
+ if (!this.isParentMilestoneLocked) {
1006
+ return '';
1007
+ }
1008
+ return 'This content is locked. Complete previous milestone to view this content.';
1009
+ }
1010
+ /**
1011
+ * Get lock message for milestone assessments
1012
+ */
1013
+ getAssessmentLockMessage() {
1014
+ if (!this.content || !this.hierarchyMapData) {
1015
+ return '';
1016
+ }
1017
+ const hashData = this.hierarchyMapData[this.content.identifier];
1018
+ // Check if hashmap has pre-computed assessment lock message
1019
+ if (hashData && hashData.assessmentLockMessage) {
1020
+ return hashData.assessmentLockMessage;
1021
+ }
1022
+ if (this.isMilestoneAssessmentLocked) {
1023
+ return 'This content is locked. Complete all mandatory items to unlock the assessment.';
1024
+ }
1025
+ return '';
1026
+ }
1027
+ shouldShowDownloadButton(content) {
1028
+ if (!content) {
1029
+ return false;
1030
+ }
1031
+ // Check if content has an artifact URL (downloadable resource)
1032
+ if (!content.artifactUrl) {
1033
+ return false;
1034
+ }
1035
+ // Check if base content resource category includes "Case Study"
1036
+ if (!this.baseContentReadData?.courseCategory ||
1037
+ this.baseContentReadData.courseCategory !== NsContent.ECourseCategory.CASE_STUDY) {
1038
+ return false;
1039
+ }
1040
+ //for public scenario check if its player plage then only enable download
1041
+ if (this.forPreview && !window.location.href.includes('/viewer/')) {
1042
+ return false;
1043
+ }
1044
+ // for logged in user check if user enrolled then only allow download
1045
+ if (!this.forPreview && !this.isEnrolled) {
1046
+ return false;
1047
+ }
1048
+ // Define downloadable MIME types
1049
+ const downloadableMimeTypes = [
1050
+ NsContent.EMimeTypes.PDF
1051
+ ];
1052
+ return downloadableMimeTypes.includes(content.mimeType);
1053
+ }
1054
+ downloadContent(content, event) {
1055
+ if (event) {
1056
+ event.preventDefault();
1057
+ event.stopPropagation();
1058
+ }
1059
+ const pageId = `app/toc/pageId/${content.identifier}`;
1060
+ this.resourceDownloadHelperSvc.downloadPDF(content, pageId);
1061
+ console.log('content', content);
1062
+ console.log('baseContent', this.baseContentReadData);
1063
+ }
1064
+ /**
1065
+ * View milestone achievement - calls the achievement API and shows the result
1066
+ */
1067
+ viewMilestoneAchievement(event) {
1068
+ if (event) {
1069
+ event.preventDefault();
1070
+ event.stopPropagation();
1071
+ }
1072
+ if (!this.content || !this.batchId || this.achievementLoading) {
1073
+ return;
1074
+ }
1075
+ // Get user ID from ConfigurationsService
1076
+ const userId = this.configSvc?.userProfile?.userId;
1077
+ if (!userId) {
1078
+ console.error('User ID not found');
1079
+ return;
1080
+ }
1081
+ // Extract milestone ID (e.g., "m1", "m2") from the content name or index
1082
+ // Try to get milestone number from the index or extract from content
1083
+ let milestoneId = 'm' + (this.index - 1); // index is typically 1-based, milestones are 0-based
1084
+ // If content name contains milestone number, extract it
1085
+ if (this.content.name) {
1086
+ const match = this.content.name.match(/milestone\s*(\d+)/i);
1087
+ if (match) {
1088
+ milestoneId = 'm' + match[1];
1089
+ }
1090
+ }
1091
+ const courseId = this.baseContentReadData?.identifier || this.rootId;
1092
+ this.achievementLoading = true;
1093
+ this.appTocSvc.generateMilestoneAchievement(userId, courseId, this.batchId, milestoneId).subscribe({
1094
+ next: (response) => {
1095
+ this.achievementLoading = false;
1096
+ console.log('Achievement generated successfully:', response);
1097
+ // Show achievement dialog or handle response
1098
+ if (response && response.result) {
1099
+ // Open a dialog to show the achievement
1100
+ this.dialog.open(CertificateDialogComponent, {
1101
+ width: '1300px',
1102
+ data: {
1103
+ cet: response.result.printUri || response.result.svgData,
1104
+ certId: response.result.identifier,
1105
+ isAchievement: true
1106
+ },
1107
+ });
1108
+ }
1109
+ },
1110
+ error: (error) => {
1111
+ this.achievementLoading = false;
1112
+ // Show error message in snackbar
1113
+ const errorMessage = error?.error?.result?.message || error?.message || 'Failed to generate achievement';
1114
+ this.snackBar.open(errorMessage, 'Close', {
1115
+ duration: 5000,
1116
+ horizontalPosition: 'center',
1117
+ verticalPosition: 'bottom',
1118
+ panelClass: ['error-snackbar']
1119
+ });
1120
+ console.error('Error generating achievement:', error);
1121
+ }
1122
+ });
1123
+ }
1124
+ /**
1125
+ * Check if text is truncated (has ellipsis) - for single line text
1126
+ * @param element The HTMLElement to check
1127
+ * @returns true if text is truncated, false otherwise
1128
+ */
1129
+ isTextTruncated(element) {
1130
+ if (!element)
1131
+ return false;
1132
+ return element.offsetWidth < element.scrollWidth;
1133
+ }
1134
+ /**
1135
+ * @param element The HTMLElement to check
1136
+ * @returns true if text is truncated, false otherwise
1137
+ */
1138
+ isMultiLineTruncated(element) {
1139
+ if (!element)
1140
+ return false;
1141
+ return element.scrollHeight > element.clientHeight;
1142
+ }
1143
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AppTocContentCardV2Component, deps: [{ token: i1.EventService }, { token: i2.MatLegacyDialog }, { token: i0.Renderer2 }, { token: i3.CertificateService }, { token: i4.AppTocService }, { token: i5.ContentLanguageService }, { token: i6.ResourceDownloadHelperService }, { token: i1.ConfigurationsService }, { token: i7.MatLegacySnackBar }], target: i0.ɵɵFactoryTarget.Component }); }
1144
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: AppTocContentCardV2Component, selector: "ws-widget-app-toc-content-card-v2", inputs: { content: "content", expandAll: "expandAll", rootId: "rootId", rootContentType: "rootContentType", forPreview: "forPreview", batchId: "batchId", componentName: "componentName", index: "index", pathSet: "pathSet", expandActive: "expandActive", hierarchyMapData: "hierarchyMapData", batchData: "batchData", isPreAssessment: "isPreAssessment", baseContentReadData: "baseContentReadData", mlCourse: "mlCourse", parentMilestoneLocked: "parentMilestoneLocked" }, usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"content && !isPreAssessment\">\n <ng-container *ngIf=\"isCollection && !isModule\">\n <ng-container [ngTemplateOutlet]=\"collectionTemplate\">\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"isCollection && isModule\">\n <ng-container *ngIf=\"content?.moduleResourseCount\">\n <ng-container [ngTemplateOutlet]=\"collectionTemplate\">\n </ng-container>\n </ng-container>\n </ng-container>\n\n <div *ngIf=\"isResource\" class=\"resource-container\"\n [ngClass]=\"pathSet?.has(content?.identifier) && isEnrolled ? 'content-active-resource': 'content-not-active-resource'\">\n <div class=\"resource flex sm:flex-row flex-start width-expand w-100 sm:pr-4 sm:w-auto\"\n [ngClass]=\"{'activeResource': pathSet?.has(content?.identifier) && isEnrolled}\">\n <!-- Lock message for curated programs only (shown above content) -->\n <ng-container *ngIf=\"content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT && checkForCuratedProgram &&\n !isContentUnlocked\">\n <div class=\"content-locking flex w-full flex-middle mb-2 gap-3\">\n <mat-icon class=\"lock-icon\">lock</mat-icon>\n <span class=\"lock-message mat-body-2\">\n The content is locked. Complete program or all courses to view this module\n </span>\n </div>\n </ng-container>\n <ng-container *ngIf=\"content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT && checkForCuratedProgram &&\n isContentUnlocked\">\n <div class=\"content-locking flex w-full flex-middle mb-2 gap-3\">\n <mat-icon class=\"unlock-icon\">lock_open_right</mat-icon>\n <span class=\"unlock-message mat-body-2\">\n This content is unlocked.\n </span>\n </div>\n </ng-container>\n <div class=\"flex flex-wrap items-start justify-start sm:justify-end\">\n <!-- <button *ngIf=\"!forPreview && content?.artifactUrl && !isXSmall && isAllowed && isEnabled\" type=\"button\"\n mat-icon-button class=\"\" [matMenuTriggerFor]=\"buttonMenu\">\n <mat-icon>more_vertical</mat-icon>\n </button> -->\n <ng-container *ngIf=\"isEnrolled && !isMilestoneLocked && !isParentMilestoneLocked\">\n <ng-container\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) ; else elseBlock\">\n\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) == 2\">\n <div class=\"completed\">\n <div>\n <mat-icon class=\"completed-icon\" [color]=\"blue\">check_circle</mat-icon>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\n <circle-progress class=\"flex items-center progress\"\n [percent]=\"getCompletionPercentage(content?.identifier)\" [radius]=\"10\"\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [space]=\"-2\"\n [outerStrokeColor]=\"progressColor2()\" [innerStrokeColor]=\"'rgba(0, 0, 0, 0.16)'\"\n [animation]=\"true\" [animationDuration]=\"250\" [showTitle]=\"false\" [showUnits]=\"false\"\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\" [backgroundStrokeWidth]=\"3\"\n matTooltip=\"In progress\" [showZeroOuterStroke]=false [backgroundPadding]=\"-9\"\n [startFromZero]=\"false\" [backgroundPadding]=\"0\" [imageHeight]=\"22\" [imageWidth]=\"22\"\n [showBackground]=\"false\" [outerStrokeLinecap]=\"'butt'\">\n </circle-progress>\n <!-- <ws-widget-content-progress *ngIf=\"content?.identifier\" [forPreview]=\"forPreview\"\n [contentId]=\"content?.identifier\" class=\"progress-bar-thin\" [progress]=\"content?.completionPercentage\"\n [progressType]=\"'percentage'\">\n </ws-widget-content-progress> -->\n </ng-container>\n </ng-container>\n <ng-template #elseBlock>\n <circle-progress class=\"flex items-center progress\" [percent]=\"0\" [radius]=\"11\"\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [outerStrokeColor]=\"'#808080'\"\n [innerStrokeColor]=\"'#808080'\" [animation]=\"true\" [space]=\"-2\" [showUnits]=\"false\"\n [animationDuration]=\"250\" [showTitle]=\"false\" [backgroundPadding]=\"0\"\n [backgroundPadding]=\"-9\" [outerStrokeLinecap]=\"'butt'\" matTooltip=\"Not started\"\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\" [imageHeight]=\"22\"\n [imageWidth]=\"22\" [showBackground]=\"false\"></circle-progress>\n <!-- <p>no data</p> -->\n </ng-template>\n </ng-container>\n </div>\n <!-- deactivated as per NIC CEO requirement to access course wthout login -->\n <!-- For locked assessments: show content but make it non-clickable -->\n <div class=\"width-expand\" *ngIf=\"isMilestoneAssessmentLocked && isEnrolled; else clickableContent\"\n [ngClass]=\"{'ml-3': isEnrolled}\">\n <div class=\"text-truncate opacity-60\">\n <div class=\"flex flex-col sm:flex-row flex-wrap\">\n <div class=\"flex items-center gap-2 w-full\">\n <mat-icon class=\"text-gray-500\">lock</mat-icon>\n <p class=\"margin-remove text-truncate mat-body-2 flex-auto font-bold nodtranslate text-gray-600\"\n [matTooltip]=\"(content?.name + (content?.contextCategory && (content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT) ? ' - ' + content?.contextCategory : '')).length > 50 ? (content?.name + (content?.contextCategory && (content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT) ? ' - ' + content?.contextCategory : '')) : ''\"\n matTooltipPosition=\"above\">\n {{ (content?.name + (content?.contextCategory && (content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT )? ' - ' + content?.contextCategory : '')) | truncate:50 }}\n </p>\n </div>\n <span class=\"content-type optional-span nodtranslate\" *ngIf=\"content?.optionalReading\">{{\n 'playerbrief.optional' | translate | titlecase}} </span>\n </div>\n <!-- for default grey icons -->\n <ng-container *ngIf=\"!pathSet?.has(content?.identifier) || !isEnrolled\">\n <div class=\"resicons ws-mat-black60-text\">\n <img src=\"/assets/icons/content/grey/video.svg\" alt=\"Video\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\n content?.mimeType ==='application/x-mpegURL'\">\n <img src=\"/assets/icons/content/grey/audio.svg\" alt=\"Audio\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'audio/mpeg'\">\n <img src=\"/assets/icons/content/grey/pdf.svg\" alt=\"PDF\" class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/pdf'\">\n <img src=\"/assets/icons/content/grey/link.svg\" alt=\"InteractiveContent\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\n <img src=\"/assets/icons/content/grey/assessment.svg\" alt=\"Assessment\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\n <img src=\"/assets/icons/content/grey/content_copy.svg\" class=\"contenticon\" alt=\"Course\"\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\n <img src=\"/assets/icons/content/grey/module.svg\" class=\"float-left margin-right-xs\"\n alt=\"offline sessions\" *ngIf=\"content.mimeType === 'application/offline'\">\n\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ content?.maxQuestions\n }} {{ 'playerbrief.questions' | translate | titlecase}}</span>\n </ng-container>\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ (content?.duration||\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\n pipeDurationTransform:\n 'hms'\n }}</span>\n </ng-container>\n </div>\n </ng-container>\n </div>\n \n <!-- Lock message displayed BELOW assessment details when locked -->\n <div class=\"content-locking flex w-full flex-middle mt-2 gap-2 px-2 py-1 bg-orange-50 border-l-4 border-orange-400\">\n <mat-icon class=\"lock-icon text-orange-600\" style=\"font-size: 18px; width: 18px; height: 18px;\">lock</mat-icon>\n <span class=\"lock-message mat-body-2 text-orange-800\" style=\"font-size: 13px;\">\n This content is locked. Complete all mandatory items to unlock the assessment.\n </span>\n </div>\n </div>\n \n <!-- Clickable content template (when NOT locked) -->\n <ng-template #clickableContent>\n <a class=\"width-expand\"\n [class.disabled]=\"(forPreview || !isEnabled || !isEnrolled || !isBatchInProgess || !isContentUnlocked || isParentMilestoneLocked) ? true : null\"\n [ngClass]=\"{'ml-3': isEnrolled}\"\n [routerLink]=\"(isAllowed && !forPreview && isEnabled && !isParentMilestoneLocked) ? resourceLink.url : null\"\n [queryParams]=\"(isAllowed && !forPreview && isEnabled && !isParentMilestoneLocked) ? resourceLink.queryParams : null\"\n [matTooltip]=\"isParentMilestoneLocked ? 'This content is locked. Complete previous milestone to view this content.' : ''\"\n matTooltipPosition=\"above\">\n <div [ngClass]=\"{'resource-active': pathSet?.has(content?.identifier) && isEnrolled}\"></div>\n <div class=\"text-truncate \" [ngClass]=\"{'cursor-pointer': !isEnabled && isEnrolled}\"\n (click)=\"content.viewChildren = !content.viewChildren; raiseTelemetry(); changeResource()\">\n <div class=\"flex flex-col sm:flex-row flex-wrap\">\n <p class=\"margin-remove text-truncate mat-body-2 flex-auto font-bold nodtranslate\"\n [ngClass]=\"{'text-active': pathSet?.has(content?.identifier) && isEnrolled}\"\n [matTooltip]=\"(content?.name + (content?.contextCategory && (content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT) ? ' - ' + content?.contextCategory : '')).length > 50 ? (content?.name + (content?.contextCategory && (content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT) ? ' - ' + content?.contextCategory : '')) : ''\"\n matTooltipPosition=\"above\">\n {{ (content?.name + (content?.contextCategory && (content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT)? ' - ' + content?.contextCategory : '')) | truncate:50 }}\n </p>\n <span class=\"content-type optional-span nodtranslate\" *ngIf=\"content?.optionalReading\">{{\n 'playerbrief.optional' | translate | titlecase}} </span>\n </div>\n <!-- for default grey icons -->\n <ng-container *ngIf=\"!pathSet?.has(content?.identifier) || !isEnrolled\">\n <div class=\"resicons ws-mat-black60-text\">\n <img src=\"/assets/icons/content/grey/video.svg\" alt=\"Video\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\n content?.mimeType ==='application/x-mpegURL'\">\n <img src=\"/assets/icons/content/grey/audio.svg\" alt=\"Audio\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'audio/mpeg'\">\n <img src=\"/assets/icons/content/grey/pdf.svg\" alt=\"PDF\" class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/pdf'\">\n <img src=\"/assets/icons/content/grey/link.svg\" alt=\"InteractiveContent\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\n <img src=\"/assets/icons/content/grey/assessment.svg\" alt=\"Assessment\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\n <img src=\"/assets/icons/content/grey/content_copy.svg\" class=\"contenticon\" alt=\"Course\"\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\n <img src=\"/assets/icons/content/grey/module.svg\" class=\"float-left margin-right-xs\"\n alt=\"offline sessions\" *ngIf=\"content.mimeType === 'application/offline'\">\n\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ content?.maxQuestions\n }} {{ 'playerbrief.questions' | translate | titlecase}}</span>\n </ng-container>\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ (content?.duration||\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\n pipeDurationTransform:\n 'hms'\n }}</span>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- for white icons when content highlighted -->\n <ng-container *ngIf=\"pathSet?.has(content?.identifier) && isEnrolled\">\n <div class=\"resicons ws-mat-white-text\">\n <img src=\"/assets/icons/content/white/video.svg\" alt=\"Video\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\n content?.mimeType ==='application/x-mpegURL'\">\n <img src=\"/assets/icons/content/white/audio.svg\" alt=\"Audio\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'audio/mpeg'\">\n <img src=\"/assets/icons/content/white/pdf.svg\" alt=\"PDF\" class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/pdf'\">\n <img src=\"/assets/icons/content/white/link.svg\" alt=\"InteractiveContent\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\n <img src=\"/assets/icons/content/white/assessment.svg\" alt=\"Assessment\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\n <img src=\"/assets/icons/content/white/content_copy.svg\" class=\"contenticon\" alt=\"Course\"\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\n <img src=\"/assets/icons/content/white/module.svg\" class=\"float-left margin-right-xs\"\n alt=\"offline sessions\" *ngIf=\"content.mimeType === 'application/offline'\">\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ content?.maxQuestions\n }} {{ 'playerbrief.questions' | translate | titlecase}}</span>\n </ng-container>\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ (content?.duration||\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\n pipeDurationTransform:\n 'hms'\n }}</span>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Download button for pdf resources -->\n <ng-container *ngIf=\"shouldShowDownloadButton(content)\">\n <div class=\"download-btn mat-body-2 mt-2 sm:mt-1\" (click)=\"downloadContent(content, $event)\"\n [ngClass]=\"{'active': pathSet?.has(content?.identifier)}\">\n <a class=\"download-link flex items-center\">\n <span class=\"\">Download</span>\n </a>\n </div>\n </ng-container>\n </div>\n </a>\n </ng-template>\n </div>\n </div>\n</ng-container>\n\n<mat-menu #buttonMenu=\"matMenu\">\n <a mat-menu-item [routerLink]=\"'../' + content?.identifier + '/overview'\" [queryParams]=\"contextPath\"\n class=\"flex flex-middle\">\n <mat-icon>toc</mat-icon>\n <h3 class=\"margin-remove nodtranslate\">\n View Details\n </h3>\n </a>\n</mat-menu>\n\n<ng-template #collectionTemplate>\n <ng-container *ngIf=\"isCollection\">\n <div class=\"collection-wrapper p-4 flex flex-col position-relative\" [ngClass]=\"{'open': check(content),\n 'close': !content.viewChildren,\n 'course':!isModule, 'module': isModule,\n 'content-active': pathSet?.has(content.identifier) && isEnrolled}\">\n <div class=\"card-collection w-auto sm:w-100 padding-right-xl\">\n <!-- <img class=\"card-thumbnail ws-mat-primary-lite-background\" [src]=\"content?.appIcon\" alt=\"Thumbnail\"\n (click)=\"content.viewChildren = !content.viewChildren\" [wsUtilsDefaultThumbnail]=\"defaultThumbnail\" /> -->\n <div class=\"flex flex-col flex-wrap flex-between width-expand pr-0 w-100 \">\n <div class=\"text-truncate\" [ngClass]=\"{'cursor-pointer': !isEnabled}\"\n (click)=\"content.viewChildren = !content.viewChildren\">\n <div class=\"flex items-center justify-center mb-1 sm:flex-row\">\n <ng-container\n *ngIf=\"isModule && isEnrolled && !isMilestoneLocked && !isParentMilestoneLocked\">\n <ng-container\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) ; else elseBlock\">\n\n <ng-container *ngIf=\"getCompletionStatus(content.identifier) == 2\">\n <div class=\"completed mr-2\">\n <div>\n <mat-icon class=\"completed-icon\" [color]=\"blue\">check_circle</mat-icon>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\n <circle-progress class=\"flex items-center progress mr-1\"\n [percent]=\"getCompletionPercentage(content?.identifier)\" [radius]=\"10\"\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [space]=\"-2\"\n [outerStrokeColor]=\"progressColor2()\"\n [innerStrokeColor]=\"'rgba(0, 0, 0, 0.16)'\" [animation]=\"true\"\n [animationDuration]=\"250\" [showTitle]=\"false\" [showUnits]=\"false\"\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\"\n [backgroundStrokeWidth]=\"3\" matTooltip=\"In progress\"\n [showZeroOuterStroke]=false [backgroundPadding]=\"-7\" [startFromZero]=\"false\"\n [backgroundPadding]=\"0\" [imageHeight]=\"18\" [imageWidth]=\"18\"\n [showBackground]=\"false\" [outerStrokeLinecap]=\"'butt'\">\n </circle-progress>\n </ng-container>\n </ng-container>\n <ng-template #elseBlock>\n <circle-progress class=\"flex items-center progress mr-1\" [percent]=\"0\" [radius]=\"11\"\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [outerStrokeColor]=\"'#808080'\"\n [innerStrokeColor]=\"'#808080'\" [animation]=\"true\" [space]=\"-2\"\n [showUnits]=\"false\" [animationDuration]=\"250\" [showTitle]=\"false\"\n [backgroundPadding]=\"0\" [backgroundPadding]=\"-9\" [outerStrokeLinecap]=\"'butt'\"\n matTooltip=\"Not started\" [showSubtitle]=\"false\" [showInnerStroke]=\"true\"\n [clockwise]=\"true\" [imageHeight]=\"22\" [imageWidth]=\"22\"\n [showBackground]=\"false\"></circle-progress>\n </ng-template>\n </ng-container>\n <div\n [ngClass]=\"{'collection-active-class': pathSet?.has(content?.identifier) && isEnrolled}\">\n </div>\n <img *ngIf=\"isMilestoneLocked\" src=\"assets/icons/hubs/lock.svg\" alt=\"Locked\"\n class=\"lock-icon mr-2 margin-bottom-xxs\">\n <div class=\"flex-auto flex flex-col\" style=\"min-width: 0;\">\n <p class=\"margin-remove text-truncate mat-subheading-1 font-bold nodtranslate\"\n [ngClass]=\"{'text-active': pathSet?.has(content.identifier) && isEnrolled}\"\n [matTooltip]=\"content?.name?.length > 50 ? content?.name : ''\"\n matTooltipPosition=\"above\">\n <span>{{isMilestone ? index -1 : index}}. </span>{{ content?.name | truncate:50 }}\n </p>\n <div class=\"mt-1\" *ngIf=\"isMilestone && isMilestoneLocked\">\n <span class=\"locked-text\">Locked</span>\n </div>\n <div class=\"mt-1\" *ngIf=\"content?.isMandatory\">\n <span class=\"mandatory-text mat-caption\">Mandatory</span>\n </div>\n </div>\n \n <div class=\"type-container resource mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Resource'\">\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\n <span class=\"nodtranslate\">Resource</span>\n </div>\n <div class=\"type-container module mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Collection'\">\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\n <span class=\"nodtranslate\">Module</span>\n </div>\n <div class=\"type-container course mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Course'\">\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\n <span class=\"nodtranslate\">Course</span>\n </div>\n </div>\n <!-- Milestone Badge -->\n <div *ngIf=\"isMilestone\" class=\"milestone-badge mt-2 mb-2\">\n <span class=\"milestone-badge-text nodtranslate\">Milestone {{index - 1}}</span>\n </div>\n <!-- Milestone Description (2 lines with ellipsis) -->\n <p #milestoneDescRef *ngIf=\"isMilestone && content?.description\" class=\"milestone-description mt-2 nodtranslate\"\n [matTooltip]=\"isMultiLineTruncated(milestoneDescRef) ? content?.description : ''\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"multiline-tooltip\">\n {{ content?.description }}\n </p>\n <div class=\"flex flex-row gap-3 items-center content-key-values mt-2\">\n <mat-icon *ngIf=\"!isModule\" alt=\"course\"\n class=\"time-icon icon-color\">video_library</mat-icon>\n <img *ngIf=\"isModule\" alt=\"Module\" class=\"time-icon\"\n src=\"/assets/icons/content/grey/module.svg\">\n <div class=\"text-xs nodtranslate\">{{ (hierarchyMapData[content?.identifier]?.duration ||\n 120)|\n pipeDurationTransform: 'hms' }}</div>\n\n <ng-container *ngIf=\"content?.moduleCount\">\n <div class=\"flex items-center\">\n <span class=\"period\"></span>\n </div>\n <div class=\"text-xs nodtranslate\">{{content?.moduleCount}} {{content?.moduleCount > 1?\n 'modules' :\n 'module'}}</div>\n </ng-container>\n <ng-container *ngIf=\"content?.leafNodesCount\">\n <div class=\"flex items-center\">\n <span class=\"period\"></span>\n </div>\n <div class=\"text-xs nodtranslate\">{{content?.leafNodesCount}} {{content?.leafNodesCount\n >1 ? 'items':\n 'item'}}</div>\n </ng-container>\n </div>\n <!-- Milestone Completion Progress -->\n <div *ngIf=\"isMilestone && isEnrolled && !isMilestoneLocked\" class=\"milestone-progress mt-2 flex items-center justify-between\">\n <div>\n <span class=\"milestone-progress-text nodtranslate\">{{getMilestoneCompletedCount()}} of\n {{content?.leafNodesCount || 0}} completed</span>\n </div>\n <!-- View Achievement Button for completed milestones - Outside clickable area -->\n <div *ngIf=\"isMilestone && isEnrolled && (getCompletionPercentage(content?.identifier) >= 100 || getCompletionStatus(content?.identifier) === 2)\"\n class=\"view-achievement-container mt-2\">\n <button type=\"button\" class=\"view-achievement-btn\" [disabled]=\"achievementLoading\"\n (click)=\"viewMilestoneAchievement($event)\">\n <span *ngIf=\"!achievementLoading\">View Achievement</span>\n <mat-spinner *ngIf=\"achievementLoading\" [diameter]=\"16\" \n [strokeWidth]=\"2\" color=\"primary\" class=\"inline-spinner\"></mat-spinner>\n </button>\n </div>\n </div>\n <!-- Unlock Criteria Message for Locked Milestones -->\n <div *ngIf=\"isMilestone && isEnrolled && isMilestoneLocked\" class=\"milestone-locked-message mt-2\">\n <span class=\"locked-criteria-text mat-caption\">\n {{ getMilestoneUnlockMessage() }}\n </span>\n </div>\n \n </div>\n <!-- For course progress to be shown -->\n <ng-container *ngIf=\"isEnrolled && !isMilestoneLocked && !isParentMilestoneLocked\">\n <ng-container\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) && content.primaryCategory === 'Course'\">\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) == 2\">\n <div class=\"flex flex-1\">\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\n <div class=\"flex flex-row justify-end w-full \">\n <span class=\"mat-body-2 nodtranslate \">\n {{getCompletionPercentage(content?.identifier)}}%</span>\n </div>\n\n <ws-widget-content-progress [contentId]=\"content?.progress\"\n [progress]=\"getCompletionPercentage(content?.identifier)\"\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\n </ws-widget-content-progress>\n </div>\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\n <a class=\"ml-5 certificate-btn\"\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\n <span class=\"nodtranslate\">Certificate</span>\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\n class=\"ml-2\">arrow_downward</mat-icon>\n <div class=\"center flex flex-middle certificate-loader\"\n *ngIf=\"downloadCertificateLoading\">\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\n [diameter]=\"16\"></mat-spinner>\n </div>\n </a>\n </ng-container>\n </div>\n <!-- <circle-progress class=\"flex items-center progress\" [percent]=\"100\" [radius]=\"12\"\n [outerStrokeWidth]=\"3\" [innerStrokeWidth]=\"3\" [space]=\"-3\"\n [outerStrokeColor]=\"progressColor()\" [innerStrokeColor]=\"'rgba(0,0,0,.16)'\"\n [animation]=\"true\" [animationDuration]=\"300\" [showTitle]=\"false\" [showUnits]=\"false\"\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\" [backgroundStrokeWidth]=\"3\"\n [showZeroOuterStroke]=false [backgroundPadding]=\"-9\" [startFromZero]=\"false\"\n [backgroundPadding]=\"0\" [imageHeight]=\"24\" [imageWidth]=\"24\" [showBackground]=\"false\"\n [outerStrokeLinecap]=\"'butt'\">\n </circle-progress> -->\n </ng-container>\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\n <div class=\"flex flex-1\">\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\n <div class=\"flex flex-row justify-end w-full ws-mat-black-text\">\n <span class=\"mat-body-2 ws-mat-black-text nodtranslate\">\n {{getCompletionPercentage(content?.identifier)}}%</span>\n </div>\n\n <ws-widget-content-progress [contentId]=\"content?.progress\"\n [progress]=\"getCompletionPercentage(content?.identifier)\"\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\n </ws-widget-content-progress>\n </div>\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\n <a class=\"ml-5 certificate-btn\"\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\n <span class=\"nodtranslate\">Certificate</span>\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\n class=\"ml-2\">arrow_downward</mat-icon>\n <div class=\"center flex flex-middle certificate-loader\"\n *ngIf=\"downloadCertificateLoading\">\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\n [diameter]=\"16\"></mat-spinner>\n </div>\n </a>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n </ng-container>\n\n <div class=\"see-all-container\">\n <a href=\"javascript:void(0)\" role=\"button\"\n (click)=\"content.viewChildren = !content.viewChildren; expandActive = false\"\n class=\"see-all-btn tab custom-chevron customicon\" mat-button>\n <mat-icon *ngIf=\"!content.viewChildren && !isModule\">keyboard_arrow_down</mat-icon>\n <mat-icon *ngIf=\"content.viewChildren && !isModule\">keyboard_arrow_up</mat-icon>\n <mat-icon *ngIf=\"!content.viewChildren && isModule\">add</mat-icon>\n <mat-icon *ngIf=\"content.viewChildren && isModule\">remove</mat-icon>\n </a>\n </div>\n </div>\n </div>\n </div>\n <div class=\"child-wrapper \" *ngIf=\"content.viewChildren\" [ngClass]=\"{'open': content.viewChildren,\n 'close': !content.viewChildren,\n 'course':!isModule,\n 'module': isModule}\" [@panelInOut]>\n <div class=\"children-container\" [ngClass]=\"{'module': isModule, '': !isModule}\">\n <ws-widget-app-toc-content-card-v2 [forPreview]=\"forPreview\" [componentName]=\"componentName\"\n [content]=\"child\" [expandAll]=\"expandAll\" [rootId]=\"rootId\" [batchId]=\"batchId\"\n [rootContentType]=\"rootContentType\" [index]=\"j+1\" [baseContentReadData]=\"baseContentReadData\"\n [pathSet]=\"pathSet\" [hierarchyMapData]=\"hierarchyMapData\" [batchData]=\"batchData\"\n [mlCourse]=\"mlCourse\" [parentMilestoneLocked]=\"isMilestoneLocked || isParentMilestoneLocked\"\n *ngFor=\"let child of content?.children; trackBy: contentTrackBy; let j= index;let isFirst = first\"\n [ngClass]=\"{'moduleCard': checkIsModule(child), 'resourceCard': !checkIsModule(child), 'first': isFirst}\">\n </ws-widget-app-toc-content-card-v2>\n </div>\n </div>\n </ng-container>\n</ng-template>\n\n\n<ng-container *ngIf=\"isPreAssessment\">\n <div class=\"collection-wrapper p-4 flex flex-col position-relative\" [ngClass]=\"{'open': check(content),\n 'course':!isModule, 'module': isModule,\n 'content-active': pathSet?.has(content.identifier)}\">\n <div class=\"card-collection w-auto sm:w-100 padding-right-xl\">\n <!-- <img class=\"card-thumbnail ws-mat-primary-lite-background\" [src]=\"content?.appIcon\" alt=\"Thumbnail\"\n (click)=\"content.viewChildren = !content.viewChildren\" [wsUtilsDefaultThumbnail]=\"defaultThumbnail\" /> -->\n <div class=\"flex flex-col flex-wrap flex-between width-expand pr-0 w-100 \">\n\n <div class=\"text-truncate\" [ngClass]=\"{'cursor-pointer': !isEnabled}\"\n (click)=\"content.viewChildren = !content.viewChildren\">\n <div class=\"flex sm:flex-row flex-wrap\">\n <ng-container>\n <ng-container\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) ; else elseBlock\">\n\n <ng-container *ngIf=\"getCompletionStatus(content.identifier) == 2\">\n <div class=\"completed mr-2\">\n <div>\n <mat-icon class=\"completed-icon\" [color]=\"blue\">check_circle</mat-icon>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\n\n <circle-progress class=\"flex items-center progress mr-1\"\n [percent]=\"getCompletionPercentage(content?.identifier)\" [radius]=\"10\"\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [space]=\"-2\"\n [outerStrokeColor]=\"progressColor2()\" [innerStrokeColor]=\"'rgba(0, 0, 0, 0.16)'\"\n [animation]=\"true\" [animationDuration]=\"250\" [showTitle]=\"false\"\n [showUnits]=\"false\" [showSubtitle]=\"false\" [showInnerStroke]=\"true\"\n [clockwise]=\"true\" [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\"\n [backgroundStrokeWidth]=\"3\" matTooltip=\"In progress\" [showZeroOuterStroke]=false\n [backgroundPadding]=\"-7\" [startFromZero]=\"false\" [backgroundPadding]=\"0\"\n [imageHeight]=\"18\" [imageWidth]=\"18\" [showBackground]=\"false\"\n [outerStrokeLinecap]=\"'butt'\">\n </circle-progress>\n </ng-container>\n </ng-container>\n <ng-template #elseBlock>\n <circle-progress class=\"flex items-center progress mr-1\" [percent]=\"0\" [radius]=\"11\"\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [outerStrokeColor]=\"'#808080'\"\n [innerStrokeColor]=\"'#808080'\" [animation]=\"true\" [space]=\"-2\" [showUnits]=\"false\"\n [animationDuration]=\"250\" [showTitle]=\"false\" [backgroundPadding]=\"0\"\n [backgroundPadding]=\"-9\" [outerStrokeLinecap]=\"'butt'\" matTooltip=\"Not started\"\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\n [imageHeight]=\"22\" [imageWidth]=\"22\" [showBackground]=\"false\"></circle-progress>\n </ng-template>\n </ng-container>\n <div [ngClass]=\"{'collection-active-class': pathSet?.has(content?.identifier)}\"></div>\n <!-- <p class=\"margin-remove text-truncate mat-subheading-1 flex-auto font-bold nodtranslate\"\n [ngClass]=\"{'text-active': pathSet?.has(content.identifier)}\">\n {{index}}. {{ content?.name | truncate:50 }}\n </p> -->\n <a class=\"margin-remove text-truncate mat-subheading-1 flex-auto font-bold nodtranslate\"\n [class.disabled]=\"null\" [ngClass]=\"{'ml-3': isEnrolled}\"\n [routerLink]=\"(isAllowed && !forPreview && isEnabled) ? resourceLink.url : null\"\n [queryParams]=\"computedQueryParams\">\n <!-- {{content?.courseCategory}} -->\n <div [ngClass]=\"{'resource-active': pathSet?.has(content?.identifier)}\"></div>\n <div class=\"text-truncate \" [ngClass]=\"{'cursor-pointer': !isEnabled}\"\n (click)=\"raiseTelemetry(); changeResource()\">\n <div class=\"flex flex-col sm:flex-row flex-wrap\">\n <p class=\"margin-remove text-truncate mat-body-2 flex-auto font-bold nodtranslate\"\n [ngClass]=\"{'text-active': pathSet?.has(content?.identifier)}\"\n [matTooltip]=\"content?.name?.length > 50 ? content?.name : ''\"\n matTooltipPosition=\"above\">\n <!-- <mat-icon class=\"margin-right-xs radiobtn time-icon\">radio_button_unchecked </mat-icon> -->\n {{index}}. {{ content?.name | truncate:50 }}\n\n </p>\n <span class=\"content-type optional-span nodtranslate\"\n *ngIf=\"content?.optionalReading\">{{ 'playerbrief.optional' | translate |\n titlecase}} </span>\n </div>\n <!-- for default grey icons -->\n <ng-container *ngIf=\"!pathSet?.has(content?.identifier)\">\n <div class=\"resicons ws-mat-black60-text\">\n <img src=\"/assets/icons/content/grey/video.svg\" alt=\"Video\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\n content?.mimeType ==='application/x-mpegURL'\">\n <img src=\"/assets/icons/content/grey/audio.svg\" alt=\"Audio\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'audio/mpeg'\">\n <img src=\"/assets/icons/content/grey/pdf.svg\" alt=\"PDF\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/pdf'\">\n <!-- <img src=\"/assets/icons/content/grey/resource.svg\" alt=\"Survey\" class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/survey'\"> -->\n <img src=\"/assets/icons/content/grey/link.svg\" alt=\"InteractiveContent\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\n <img src=\"/assets/icons/content/grey/assessment.svg\" alt=\"Assessment\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\n <img src=\"/assets/icons/content/grey/content_copy.svg\" class=\"contenticon\"\n alt=\"Course\"\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\n <img src=\"/assets/icons/content/grey/module.svg\"\n class=\"float-left margin-right-xs\" alt=\"offline sessions\"\n *ngIf=\"content.mimeType === 'application/offline'\">\n\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\n\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{\n content?.maxQuestions }} {{ 'playerbrief.questions' | translate |\n titlecase}}</span>\n </ng-container>\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{\n (content?.duration||\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\n pipeDurationTransform:\n 'hms'\n }}</span>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- for white icons when content highlighted -->\n <ng-container *ngIf=\"pathSet?.has(content?.identifier)\">\n <div class=\"resicons ws-mat-white-text\">\n <img src=\"/assets/icons/content/white/video.svg\" alt=\"Video\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\n content?.mimeType ==='application/x-mpegURL'\">\n <img src=\"/assets/icons/content/white/audio.svg\" alt=\"Audio\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'audio/mpeg'\">\n <img src=\"/assets/icons/content/white/pdf.svg\" alt=\"PDF\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/pdf'\">\n <!-- <img src=\"/assets/icons/content/white/resource.svg\" alt=\"Survey\" class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/survey'\"> -->\n <img src=\"/assets/icons/content/white/link.svg\" alt=\"InteractiveContent\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\n <img src=\"/assets/icons/content/white/assessment.svg\" alt=\"Assessment\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\n <img src=\"/assets/icons/content/white/content_copy.svg\" class=\"contenticon\"\n alt=\"Course\"\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\n <img src=\"/assets/icons/content/white/module.svg\"\n class=\"float-left margin-right-xs\" alt=\"offline sessions\"\n *ngIf=\"content.mimeType === 'application/offline'\">\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\n <span class=\"resourceDuration ws-mat-white-text nodtranslate\">{{\n content?.maxQuestions }} {{ 'playerbrief.questions' | translate |\n titlecase}}</span>\n </ng-container>\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\n <span class=\"resourceDuration ws-mat-white-text nodtranslate\">{{\n (content?.duration||\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\n pipeDurationTransform:\n 'hms'\n }}</span>\n </ng-container>\n </div>\n </ng-container>\n </div>\n </a>\n <!-- <div class=\"type-container resource mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Resource'\">\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\n <span class=\"nodtranslate\">Resource</span>\n </div>\n <div class=\"type-container module mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Collection'\">\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\n <span class=\"nodtranslate\">Module</span>\n </div>\n <div class=\"type-container course mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Course'\">\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\n <span class=\"nodtranslate\">Course</span>\n </div> -->\n </div>\n\n </div>\n <!-- For course progress to be shown -->\n <ng-container>\n <ng-container\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier)\">\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) == 2\">\n <div class=\"flex flex-1\">\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\n <div class=\"flex flex-row justify-end w-full \">\n <span class=\"mat-body-2 nodtranslate \">\n {{getCompletionPercentage(content?.identifier)}}%</span>\n </div>\n\n <ws-widget-content-progress [contentId]=\"content?.progress\"\n [progress]=\"getCompletionPercentage(content?.identifier)\"\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\n </ws-widget-content-progress>\n </div>\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\n <a class=\"ml-5 certificate-btn\"\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\n <span class=\"nodtranslate\">Certificate</span>\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\n class=\"ml-2\">arrow_downward</mat-icon>\n <div class=\"center flex flex-middle certificate-loader\"\n *ngIf=\"downloadCertificateLoading\">\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\n [diameter]=\"16\"></mat-spinner>\n </div>\n </a>\n </ng-container>\n </div>\n <!-- <circle-progress class=\"flex items-center progress\" [percent]=\"100\" [radius]=\"12\"\n [outerStrokeWidth]=\"3\" [innerStrokeWidth]=\"3\" [space]=\"-3\"\n [outerStrokeColor]=\"progressColor()\" [innerStrokeColor]=\"'rgba(0,0,0,.16)'\"\n [animation]=\"true\" [animationDuration]=\"300\" [showTitle]=\"false\" [showUnits]=\"false\"\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\" [backgroundStrokeWidth]=\"3\"\n [showZeroOuterStroke]=false [backgroundPadding]=\"-9\" [startFromZero]=\"false\"\n [backgroundPadding]=\"0\" [imageHeight]=\"24\" [imageWidth]=\"24\" [showBackground]=\"false\"\n [outerStrokeLinecap]=\"'butt'\">\n </circle-progress> -->\n </ng-container>\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\n <div class=\"flex flex-1\">\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\n <div class=\"flex flex-row justify-end w-full ws-mat-black-text\">\n <span class=\"mat-body-2 ws-mat-black-text nodtranslate\">\n {{getCompletionPercentage(content?.identifier)}}%</span>\n </div>\n\n <ws-widget-content-progress [contentId]=\"content?.progress\"\n [progress]=\"getCompletionPercentage(content?.identifier)\"\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\n </ws-widget-content-progress>\n </div>\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\n <a class=\"ml-5 certificate-btn\"\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\n <span class=\"nodtranslate\">Certificate</span>\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\n class=\"ml-2\">arrow_downward</mat-icon>\n <div class=\"center flex flex-middle certificate-loader\"\n *ngIf=\"downloadCertificateLoading\">\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\n [diameter]=\"16\"></mat-spinner>\n </div>\n </a>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n </ng-container>\n\n <!-- <div class=\"see-all-container\">\n <a href=\"javascript:void(0)\" role=\"button\"\n (click)=\"content.viewChildren = !content.viewChildren; expandActive = false\"\n class=\"see-all-btn tab custom-chevron customicon\" mat-button>\n <mat-icon *ngIf=\"!content.viewChildren && !isModule\">keyboard_arrow_down</mat-icon>\n <mat-icon *ngIf=\"content.viewChildren && !isModule\">keyboard_arrow_up</mat-icon>\n <mat-icon *ngIf=\"!content.viewChildren && isModule\">add</mat-icon>\n <mat-icon *ngIf=\"content.viewChildren && isModule\">remove</mat-icon>\n </a>\n </div> -->\n </div>\n </div>\n </div>\n\n</ng-container>", styles: [".customicon{position:absolute;top:-.5em;right:0}.customicon .mat-icon{color:#1a4ca1}a.disabled{pointer-events:none;cursor:default}span.optional-span{margin-left:8px;padding:0 6px;border-radius:2px;display:inline-block;background-color:#0074b6;color:#fff;font-size:12px}.card-collection{display:flex;align-items:center;border-radius:8px}.card-collection .card-thumbnail{height:100%;margin-right:12px;cursor:pointer;border-radius:8px 0 0}@media only screen and (max-width: 469px){.card-collection{flex-direction:column;align-items:flex-start!important}.card-collection .card-thumbnail{height:100%!important;width:100%!important}.card-collection .text-truncate{white-space:unset!important}}.tab:focus{outline:1px solid!important}.custom-chevron:focus{outline:0px solid!important}.resource-container{display:flex;align-items:flex-start;flex-direction:column}.resource-container .resource{padding:16px 16px 16px 0;width:100%}.resource-container .card-thumbnail{height:100%;cursor:pointer}.resource-container .img-container{position:relative;margin-right:12px}.resource-container .img-container ws-widget-content-progress{position:absolute;left:0;right:0;bottom:5px}@media only screen and (max-width: 469px){.resource-container{flex-direction:column;align-items:flex-start!important}.resource-container .card-thumbnail{height:100%!important;width:100%!important}.resource-container .text-truncate{white-space:unset!important}}.child-meta-container{margin-top:8px;display:flex}.child-meta-container .child-structure{display:flex;align-items:center;flex-wrap:wrap}.child-meta-container .child-structure span{margin-right:12px;text-align:center;margin-bottom:8px}.child-meta-container .child-structure .structure-icon{margin-right:12px}@media only screen and (max-width: 469px){.child-meta-container{margin-left:.5rem;justify-content:space-between}}.resource-container{display:flex;align-items:center}.resource-container ws-display-content-type-icon{display:flex;align-items:center}.resource-container .resource-meta{margin-left:12px;display:flex;justify-content:space-between;align-items:center}.completed-icon{color:#1a4ca1}.collection-wrapper{padding:1rem}.collection-wrapper.course.content-active{background-color:#1a4ca1;color:#fff}.collection-wrapper.course.content-active .period{background:#fff}.collection-wrapper.course.content-active .text-active,.collection-wrapper.course.content-active .icon-color,.collection-wrapper.course.content-active .customicon .mat-icon{color:#fff}.collection-wrapper.course.content-active .progress-container span{color:#fff!important}.collection-wrapper.course.content-active .milestone-description,.collection-wrapper.course.content-active .milestone-progress-text{color:#fff}.text-active{color:#1a4ca1}.text-active.font-bold{font-weight:600}.activeResource{background-color:#1a4ca1;color:#fff;padding-top:1rem!important;padding-bottom:1rem!important}.activeResource .text-active{color:#fff}.activeResource .text-active.font-bold{font-weight:600}.activeResource .resourceDuration,.activeResource .completed-icon{color:#fff}.collection-wrapper.open{border-bottom:1px solid rgba(0,0,0,.16)}.collection-wrapper.close{border:none}.child-wrapper.open{border-radius:0 0 8px 8px}.children-container .mat-subheading-1{font:500 16px/24px Lato!important}.children-container .resource-container{margin-bottom:16px}.children-container .resource-container .resource{padding:0}.children-container .resource-container .card-thumbnail{height:65px;align-self:center}.first.resourceCard:nth-child(1) .resource{margin-top:16px!important}.first.resourceCard:nth-child(1) .activeResource{margin-top:0!important}.children-container .resourceCard:last-child .resource-container:has(.activeResource){margin-bottom:0!important}.moduleCard:not(:last-child)>.collection-wrapper.close.module{border-bottom:4px solid rgba(0,0,0,.08);border-radius:0}.moduleCard:not(:last-child)>.collection-wrapper.open.module+.child-wrapper.open{border-bottom:4px solid rgba(0,0,0,.08);border-radius:0}.collection-wrapper.open.course+.child-wrapper.open .collection-wrapper.open.module+.child-wrapper.open{background-color:#eff3f9;border-bottom:4px solid rgba(0,0,0,.08);border-radius:0}.collection-wrapper.open.module+.child-wrapper.open{background-color:#eff3f9;border-radius:0;padding-bottom:8px}.content-heading{letter-spacing:0px;color:#222}.content-type{letter-spacing:0px}.time-icon{height:16px;width:16px;font-size:16px;vertical-align:middle}.time-icon.icon-color{color:#0009}.period{width:3px;height:3px;background:#0009;border-radius:4px}.time-value{letter-spacing:0px;color:#222;text-transform:lowercase}.see-all-container{position:absolute;right:16px;top:24px}.oval-white{background:#fff 0% 0% no-repeat padding-box;border-radius:8px;padding:2px 8px}.type-container{letter-spacing:0px;display:flex;align-items:center}.type-container .rotate-90{transform:rotate(-90deg)}.type-container .custom-icon{width:18px;height:18px;font-size:18px;margin-right:8px}.type-container.resource{color:#00a9f4}.type-container.module{color:#34d6a4}.type-container.course{color:#f58634}.no-mb{margin-bottom:0!important}.w-100{width:100%}.w-auto{width:auto}.progress-bar-thin{height:5px!important}.progress-bar-thin ::ng-deep .mat-progress-bar{height:5px}.progress-bar-thin ::ng-deep .theme-igot.day-mode .mat-progress-bar-buffer{background-color:transparent!important}.progress-bar-thin ::ng-deep .theme-igot.day-mode .mat-progress-bar-background{fill:transparent}.radiobtn{color:#00000029}.resicons img{width:22px;opacity:.5;margin-top:2px;vertical-align:sub}.certificate-btn{height:24px;background:#1a4ca1;display:flex;justify-content:center;align-items:center;padding:4px 11px;color:#fff;border-radius:20px;border:1px solid white;font:400 12px/16px Lato;cursor:pointer}.certificate-btn .mat-icon{fill:#fff;color:#fff;font-size:16px;height:auto;width:auto}.view-certificate-wrapper{display:flex;border-radius:4px;border:1.5px solid rgb(0,116,182);opacity:1;padding:8px}.collection-wrapper.course,.collection-wrapper.module,.resource-container .resource{padding-left:16px;box-sizing:border-box;width:100%;overflow:hidden}.children-container.module .resource-container .resource,.course .collection-wrapper.module{padding-left:24px;box-sizing:border-box;width:100%}.course .children-container.module .resource-container .resource{padding-left:32px;box-sizing:border-box;width:100%}.course .resource-container .resource{padding-left:24px}::ng-deep .white-spinner{stroke:#fff!important}.certificate-loader ::ng-deep .mat-progress-spinner circle,.mat-spinner circle{stroke:#fff}.lock-message{background:#fff4ec;color:#d13924;padding:10px;border-radius:4px;display:block!important;width:100%}.content-locking{padding:8px 12px;margin-top:8px;margin-left:0;margin-right:0;border-radius:4px;background:#fff4ec;display:flex!important;align-items:center;gap:8px;width:100%;box-sizing:border-box}.lock-icon{color:#f3962f;font-size:20px;flex-shrink:0}.unlock-message{background:#efffec;color:#0c9600;padding:10px}.unlock-icon{color:#0c9600}.download-btn{padding:4px 12px;text-underline-position:from-font;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none;cursor:pointer;border-radius:40px;color:#1b4ca1;font-weight:700;border:1px solid #1B4CA1;display:inline-block;pointer-events:auto;position:relative;z-index:1}.activeResource .download-btn.active{color:#fff;border:1px solid #fff}.milestone-badge{display:inline-block;background-color:#fefaf4;border:1px solid #EF951E;border-radius:16px;padding:2px 12px}.milestone-badge-text{font-size:12px;font-weight:500;color:#212121}.milestone-description{font-size:14px;line-height:1.5;color:#000000b3;margin:0;display:-webkit-box!important;-webkit-line-clamp:2!important;-webkit-box-orient:vertical!important;overflow:hidden!important;text-overflow:ellipsis!important;word-break:break-word!important;white-space:normal!important;max-width:100%!important}.milestone-progress{display:flex;align-items:center}.milestone-progress-text{font-size:14px;font-weight:500;color:#0009}.milestone-locked-message{display:flex;align-items:center;padding:8px 12px;background-color:#f3962f1a;border-left:3px solid #F3962F;border-radius:4px}.locked-criteria-text{font-size:13px;font-weight:400;color:#000000b3;line-height:1.4}.locked-text{font-size:14px;font-weight:500;color:#f3962f}.mandatory-text{color:#d13924!important}.view-achievement-container{display:flex;align-items:center}.view-achievement-btn{background-color:transparent;border:1.5px solid #1a4ca1;color:#1a4ca1;border-radius:20px;padding:6px 16px;font-size:14px;font-weight:500;cursor:pointer;display:flex;align-items:center;gap:8px;transition:all .2s ease;min-width:150px}.view-achievement-btn:hover:not(:disabled){background-color:#1a4ca1;color:#fff}.view-achievement-btn:disabled{opacity:.6;cursor:not-allowed}.view-achievement-btn .inline-spinner{display:inline-block}::ng-deep .multiline-tooltip{white-space:pre-wrap!important;max-width:400px!important;word-break:break-word!important;line-height:1.4!important}\n"], dependencies: [{ kind: "directive", type: i8.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i8.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i9.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i10.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i11.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i11.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "component", type: i12.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: i13.ContentProgressComponent, selector: "ws-widget-content-progress", inputs: ["contentId", "progress", "progressType", "forPreview", "className", "customClassName"] }, { kind: "component", type: i14.CircleProgressComponent, selector: "circle-progress", inputs: ["name", "class", "backgroundGradient", "backgroundColor", "backgroundGradientStopColor", "backgroundOpacity", "backgroundStroke", "backgroundStrokeWidth", "backgroundPadding", "radius", "space", "percent", "toFixed", "maxPercent", "renderOnClick", "units", "unitsFontSize", "unitsFontWeight", "unitsColor", "outerStrokeGradient", "outerStrokeWidth", "outerStrokeColor", "outerStrokeGradientStopColor", "outerStrokeLinecap", "innerStrokeColor", "innerStrokeWidth", "titleFormat", "title", "titleColor", "titleFontSize", "titleFontWeight", "subtitleFormat", "subtitle", "subtitleColor", "subtitleFontSize", "subtitleFontWeight", "imageSrc", "imageHeight", "imageWidth", "animation", "animateTitle", "animateSubtitle", "animationDuration", "showTitle", "showSubtitle", "showUnits", "showImage", "showBackground", "showInnerStroke", "clockwise", "responsive", "startFromZero", "showZeroOuterStroke", "lazy", "options"], outputs: ["onClick"] }, { kind: "directive", type: i15.MatLegacyTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: AppTocContentCardV2Component, selector: "ws-widget-app-toc-content-card-v2", inputs: ["content", "expandAll", "rootId", "rootContentType", "forPreview", "batchId", "componentName", "index", "pathSet", "expandActive", "hierarchyMapData", "batchData", "isPreAssessment", "baseContentReadData", "mlCourse", "parentMilestoneLocked"] }, { kind: "pipe", type: i8.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: i1.PipeDurationTransformPipe, name: "pipeDurationTransform" }, { kind: "pipe", type: i16.TranslatePipe, name: "translate" }, { kind: "pipe", type: i17.TruncatePipe, name: "truncate" }], animations: [
1145
+ trigger('panelInOut', [
1146
+ transition('void => *', [
1147
+ style({ transform: 'translateY(-10%)', opacity: '0' }),
1148
+ animate(250)
1149
+ ]),
1150
+ transition('* => void', [
1151
+ animate(200, style({ transform: 'translateY(-10%)', opacity: '0' }))
1152
+ ])
1153
+ ])
1154
+ ] }); }
1155
+ }
1156
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AppTocContentCardV2Component, decorators: [{
1157
+ type: Component,
1158
+ args: [{ selector: 'ws-widget-app-toc-content-card-v2', animations: [
1159
+ trigger('panelInOut', [
1160
+ transition('void => *', [
1161
+ style({ transform: 'translateY(-10%)', opacity: '0' }),
1162
+ animate(250)
1163
+ ]),
1164
+ transition('* => void', [
1165
+ animate(200, style({ transform: 'translateY(-10%)', opacity: '0' }))
1166
+ ])
1167
+ ])
1168
+ ], template: "<ng-container *ngIf=\"content && !isPreAssessment\">\n <ng-container *ngIf=\"isCollection && !isModule\">\n <ng-container [ngTemplateOutlet]=\"collectionTemplate\">\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"isCollection && isModule\">\n <ng-container *ngIf=\"content?.moduleResourseCount\">\n <ng-container [ngTemplateOutlet]=\"collectionTemplate\">\n </ng-container>\n </ng-container>\n </ng-container>\n\n <div *ngIf=\"isResource\" class=\"resource-container\"\n [ngClass]=\"pathSet?.has(content?.identifier) && isEnrolled ? 'content-active-resource': 'content-not-active-resource'\">\n <div class=\"resource flex sm:flex-row flex-start width-expand w-100 sm:pr-4 sm:w-auto\"\n [ngClass]=\"{'activeResource': pathSet?.has(content?.identifier) && isEnrolled}\">\n <!-- Lock message for curated programs only (shown above content) -->\n <ng-container *ngIf=\"content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT && checkForCuratedProgram &&\n !isContentUnlocked\">\n <div class=\"content-locking flex w-full flex-middle mb-2 gap-3\">\n <mat-icon class=\"lock-icon\">lock</mat-icon>\n <span class=\"lock-message mat-body-2\">\n The content is locked. Complete program or all courses to view this module\n </span>\n </div>\n </ng-container>\n <ng-container *ngIf=\"content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT && checkForCuratedProgram &&\n isContentUnlocked\">\n <div class=\"content-locking flex w-full flex-middle mb-2 gap-3\">\n <mat-icon class=\"unlock-icon\">lock_open_right</mat-icon>\n <span class=\"unlock-message mat-body-2\">\n This content is unlocked.\n </span>\n </div>\n </ng-container>\n <div class=\"flex flex-wrap items-start justify-start sm:justify-end\">\n <!-- <button *ngIf=\"!forPreview && content?.artifactUrl && !isXSmall && isAllowed && isEnabled\" type=\"button\"\n mat-icon-button class=\"\" [matMenuTriggerFor]=\"buttonMenu\">\n <mat-icon>more_vertical</mat-icon>\n </button> -->\n <ng-container *ngIf=\"isEnrolled && !isMilestoneLocked && !isParentMilestoneLocked\">\n <ng-container\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) ; else elseBlock\">\n\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) == 2\">\n <div class=\"completed\">\n <div>\n <mat-icon class=\"completed-icon\" [color]=\"blue\">check_circle</mat-icon>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\n <circle-progress class=\"flex items-center progress\"\n [percent]=\"getCompletionPercentage(content?.identifier)\" [radius]=\"10\"\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [space]=\"-2\"\n [outerStrokeColor]=\"progressColor2()\" [innerStrokeColor]=\"'rgba(0, 0, 0, 0.16)'\"\n [animation]=\"true\" [animationDuration]=\"250\" [showTitle]=\"false\" [showUnits]=\"false\"\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\" [backgroundStrokeWidth]=\"3\"\n matTooltip=\"In progress\" [showZeroOuterStroke]=false [backgroundPadding]=\"-9\"\n [startFromZero]=\"false\" [backgroundPadding]=\"0\" [imageHeight]=\"22\" [imageWidth]=\"22\"\n [showBackground]=\"false\" [outerStrokeLinecap]=\"'butt'\">\n </circle-progress>\n <!-- <ws-widget-content-progress *ngIf=\"content?.identifier\" [forPreview]=\"forPreview\"\n [contentId]=\"content?.identifier\" class=\"progress-bar-thin\" [progress]=\"content?.completionPercentage\"\n [progressType]=\"'percentage'\">\n </ws-widget-content-progress> -->\n </ng-container>\n </ng-container>\n <ng-template #elseBlock>\n <circle-progress class=\"flex items-center progress\" [percent]=\"0\" [radius]=\"11\"\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [outerStrokeColor]=\"'#808080'\"\n [innerStrokeColor]=\"'#808080'\" [animation]=\"true\" [space]=\"-2\" [showUnits]=\"false\"\n [animationDuration]=\"250\" [showTitle]=\"false\" [backgroundPadding]=\"0\"\n [backgroundPadding]=\"-9\" [outerStrokeLinecap]=\"'butt'\" matTooltip=\"Not started\"\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\" [imageHeight]=\"22\"\n [imageWidth]=\"22\" [showBackground]=\"false\"></circle-progress>\n <!-- <p>no data</p> -->\n </ng-template>\n </ng-container>\n </div>\n <!-- deactivated as per NIC CEO requirement to access course wthout login -->\n <!-- For locked assessments: show content but make it non-clickable -->\n <div class=\"width-expand\" *ngIf=\"isMilestoneAssessmentLocked && isEnrolled; else clickableContent\"\n [ngClass]=\"{'ml-3': isEnrolled}\">\n <div class=\"text-truncate opacity-60\">\n <div class=\"flex flex-col sm:flex-row flex-wrap\">\n <div class=\"flex items-center gap-2 w-full\">\n <mat-icon class=\"text-gray-500\">lock</mat-icon>\n <p class=\"margin-remove text-truncate mat-body-2 flex-auto font-bold nodtranslate text-gray-600\"\n [matTooltip]=\"(content?.name + (content?.contextCategory && (content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT) ? ' - ' + content?.contextCategory : '')).length > 50 ? (content?.name + (content?.contextCategory && (content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT) ? ' - ' + content?.contextCategory : '')) : ''\"\n matTooltipPosition=\"above\">\n {{ (content?.name + (content?.contextCategory && (content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT )? ' - ' + content?.contextCategory : '')) | truncate:50 }}\n </p>\n </div>\n <span class=\"content-type optional-span nodtranslate\" *ngIf=\"content?.optionalReading\">{{\n 'playerbrief.optional' | translate | titlecase}} </span>\n </div>\n <!-- for default grey icons -->\n <ng-container *ngIf=\"!pathSet?.has(content?.identifier) || !isEnrolled\">\n <div class=\"resicons ws-mat-black60-text\">\n <img src=\"/assets/icons/content/grey/video.svg\" alt=\"Video\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\n content?.mimeType ==='application/x-mpegURL'\">\n <img src=\"/assets/icons/content/grey/audio.svg\" alt=\"Audio\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'audio/mpeg'\">\n <img src=\"/assets/icons/content/grey/pdf.svg\" alt=\"PDF\" class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/pdf'\">\n <img src=\"/assets/icons/content/grey/link.svg\" alt=\"InteractiveContent\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\n <img src=\"/assets/icons/content/grey/assessment.svg\" alt=\"Assessment\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\n <img src=\"/assets/icons/content/grey/content_copy.svg\" class=\"contenticon\" alt=\"Course\"\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\n <img src=\"/assets/icons/content/grey/module.svg\" class=\"float-left margin-right-xs\"\n alt=\"offline sessions\" *ngIf=\"content.mimeType === 'application/offline'\">\n\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ content?.maxQuestions\n }} {{ 'playerbrief.questions' | translate | titlecase}}</span>\n </ng-container>\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ (content?.duration||\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\n pipeDurationTransform:\n 'hms'\n }}</span>\n </ng-container>\n </div>\n </ng-container>\n </div>\n \n <!-- Lock message displayed BELOW assessment details when locked -->\n <div class=\"content-locking flex w-full flex-middle mt-2 gap-2 px-2 py-1 bg-orange-50 border-l-4 border-orange-400\">\n <mat-icon class=\"lock-icon text-orange-600\" style=\"font-size: 18px; width: 18px; height: 18px;\">lock</mat-icon>\n <span class=\"lock-message mat-body-2 text-orange-800\" style=\"font-size: 13px;\">\n This content is locked. Complete all mandatory items to unlock the assessment.\n </span>\n </div>\n </div>\n \n <!-- Clickable content template (when NOT locked) -->\n <ng-template #clickableContent>\n <a class=\"width-expand\"\n [class.disabled]=\"(forPreview || !isEnabled || !isEnrolled || !isBatchInProgess || !isContentUnlocked || isParentMilestoneLocked) ? true : null\"\n [ngClass]=\"{'ml-3': isEnrolled}\"\n [routerLink]=\"(isAllowed && !forPreview && isEnabled && !isParentMilestoneLocked) ? resourceLink.url : null\"\n [queryParams]=\"(isAllowed && !forPreview && isEnabled && !isParentMilestoneLocked) ? resourceLink.queryParams : null\"\n [matTooltip]=\"isParentMilestoneLocked ? 'This content is locked. Complete previous milestone to view this content.' : ''\"\n matTooltipPosition=\"above\">\n <div [ngClass]=\"{'resource-active': pathSet?.has(content?.identifier) && isEnrolled}\"></div>\n <div class=\"text-truncate \" [ngClass]=\"{'cursor-pointer': !isEnabled && isEnrolled}\"\n (click)=\"content.viewChildren = !content.viewChildren; raiseTelemetry(); changeResource()\">\n <div class=\"flex flex-col sm:flex-row flex-wrap\">\n <p class=\"margin-remove text-truncate mat-body-2 flex-auto font-bold nodtranslate\"\n [ngClass]=\"{'text-active': pathSet?.has(content?.identifier) && isEnrolled}\"\n [matTooltip]=\"(content?.name + (content?.contextCategory && (content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT) ? ' - ' + content?.contextCategory : '')).length > 50 ? (content?.name + (content?.contextCategory && (content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT) ? ' - ' + content?.contextCategory : '')) : ''\"\n matTooltipPosition=\"above\">\n {{ (content?.name + (content?.contextCategory && (content?.primaryCategory === primaryCategory.FINAL_ASSESSMENT)? ' - ' + content?.contextCategory : '')) | truncate:50 }}\n </p>\n <span class=\"content-type optional-span nodtranslate\" *ngIf=\"content?.optionalReading\">{{\n 'playerbrief.optional' | translate | titlecase}} </span>\n </div>\n <!-- for default grey icons -->\n <ng-container *ngIf=\"!pathSet?.has(content?.identifier) || !isEnrolled\">\n <div class=\"resicons ws-mat-black60-text\">\n <img src=\"/assets/icons/content/grey/video.svg\" alt=\"Video\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\n content?.mimeType ==='application/x-mpegURL'\">\n <img src=\"/assets/icons/content/grey/audio.svg\" alt=\"Audio\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'audio/mpeg'\">\n <img src=\"/assets/icons/content/grey/pdf.svg\" alt=\"PDF\" class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/pdf'\">\n <img src=\"/assets/icons/content/grey/link.svg\" alt=\"InteractiveContent\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\n <img src=\"/assets/icons/content/grey/assessment.svg\" alt=\"Assessment\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\n <img src=\"/assets/icons/content/grey/content_copy.svg\" class=\"contenticon\" alt=\"Course\"\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\n <img src=\"/assets/icons/content/grey/module.svg\" class=\"float-left margin-right-xs\"\n alt=\"offline sessions\" *ngIf=\"content.mimeType === 'application/offline'\">\n\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ content?.maxQuestions\n }} {{ 'playerbrief.questions' | translate | titlecase}}</span>\n </ng-container>\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ (content?.duration||\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\n pipeDurationTransform:\n 'hms'\n }}</span>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- for white icons when content highlighted -->\n <ng-container *ngIf=\"pathSet?.has(content?.identifier) && isEnrolled\">\n <div class=\"resicons ws-mat-white-text\">\n <img src=\"/assets/icons/content/white/video.svg\" alt=\"Video\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\n content?.mimeType ==='application/x-mpegURL'\">\n <img src=\"/assets/icons/content/white/audio.svg\" alt=\"Audio\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'audio/mpeg'\">\n <img src=\"/assets/icons/content/white/pdf.svg\" alt=\"PDF\" class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/pdf'\">\n <img src=\"/assets/icons/content/white/link.svg\" alt=\"InteractiveContent\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\n <img src=\"/assets/icons/content/white/assessment.svg\" alt=\"Assessment\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\n <img src=\"/assets/icons/content/white/content_copy.svg\" class=\"contenticon\" alt=\"Course\"\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\n <img src=\"/assets/icons/content/white/module.svg\" class=\"float-left margin-right-xs\"\n alt=\"offline sessions\" *ngIf=\"content.mimeType === 'application/offline'\">\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ content?.maxQuestions\n }} {{ 'playerbrief.questions' | translate | titlecase}}</span>\n </ng-container>\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{ (content?.duration||\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\n pipeDurationTransform:\n 'hms'\n }}</span>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- Download button for pdf resources -->\n <ng-container *ngIf=\"shouldShowDownloadButton(content)\">\n <div class=\"download-btn mat-body-2 mt-2 sm:mt-1\" (click)=\"downloadContent(content, $event)\"\n [ngClass]=\"{'active': pathSet?.has(content?.identifier)}\">\n <a class=\"download-link flex items-center\">\n <span class=\"\">Download</span>\n </a>\n </div>\n </ng-container>\n </div>\n </a>\n </ng-template>\n </div>\n </div>\n</ng-container>\n\n<mat-menu #buttonMenu=\"matMenu\">\n <a mat-menu-item [routerLink]=\"'../' + content?.identifier + '/overview'\" [queryParams]=\"contextPath\"\n class=\"flex flex-middle\">\n <mat-icon>toc</mat-icon>\n <h3 class=\"margin-remove nodtranslate\">\n View Details\n </h3>\n </a>\n</mat-menu>\n\n<ng-template #collectionTemplate>\n <ng-container *ngIf=\"isCollection\">\n <div class=\"collection-wrapper p-4 flex flex-col position-relative\" [ngClass]=\"{'open': check(content),\n 'close': !content.viewChildren,\n 'course':!isModule, 'module': isModule,\n 'content-active': pathSet?.has(content.identifier) && isEnrolled}\">\n <div class=\"card-collection w-auto sm:w-100 padding-right-xl\">\n <!-- <img class=\"card-thumbnail ws-mat-primary-lite-background\" [src]=\"content?.appIcon\" alt=\"Thumbnail\"\n (click)=\"content.viewChildren = !content.viewChildren\" [wsUtilsDefaultThumbnail]=\"defaultThumbnail\" /> -->\n <div class=\"flex flex-col flex-wrap flex-between width-expand pr-0 w-100 \">\n <div class=\"text-truncate\" [ngClass]=\"{'cursor-pointer': !isEnabled}\"\n (click)=\"content.viewChildren = !content.viewChildren\">\n <div class=\"flex items-center justify-center mb-1 sm:flex-row\">\n <ng-container\n *ngIf=\"isModule && isEnrolled && !isMilestoneLocked && !isParentMilestoneLocked\">\n <ng-container\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) ; else elseBlock\">\n\n <ng-container *ngIf=\"getCompletionStatus(content.identifier) == 2\">\n <div class=\"completed mr-2\">\n <div>\n <mat-icon class=\"completed-icon\" [color]=\"blue\">check_circle</mat-icon>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\n <circle-progress class=\"flex items-center progress mr-1\"\n [percent]=\"getCompletionPercentage(content?.identifier)\" [radius]=\"10\"\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [space]=\"-2\"\n [outerStrokeColor]=\"progressColor2()\"\n [innerStrokeColor]=\"'rgba(0, 0, 0, 0.16)'\" [animation]=\"true\"\n [animationDuration]=\"250\" [showTitle]=\"false\" [showUnits]=\"false\"\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\"\n [backgroundStrokeWidth]=\"3\" matTooltip=\"In progress\"\n [showZeroOuterStroke]=false [backgroundPadding]=\"-7\" [startFromZero]=\"false\"\n [backgroundPadding]=\"0\" [imageHeight]=\"18\" [imageWidth]=\"18\"\n [showBackground]=\"false\" [outerStrokeLinecap]=\"'butt'\">\n </circle-progress>\n </ng-container>\n </ng-container>\n <ng-template #elseBlock>\n <circle-progress class=\"flex items-center progress mr-1\" [percent]=\"0\" [radius]=\"11\"\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [outerStrokeColor]=\"'#808080'\"\n [innerStrokeColor]=\"'#808080'\" [animation]=\"true\" [space]=\"-2\"\n [showUnits]=\"false\" [animationDuration]=\"250\" [showTitle]=\"false\"\n [backgroundPadding]=\"0\" [backgroundPadding]=\"-9\" [outerStrokeLinecap]=\"'butt'\"\n matTooltip=\"Not started\" [showSubtitle]=\"false\" [showInnerStroke]=\"true\"\n [clockwise]=\"true\" [imageHeight]=\"22\" [imageWidth]=\"22\"\n [showBackground]=\"false\"></circle-progress>\n </ng-template>\n </ng-container>\n <div\n [ngClass]=\"{'collection-active-class': pathSet?.has(content?.identifier) && isEnrolled}\">\n </div>\n <img *ngIf=\"isMilestoneLocked\" src=\"assets/icons/hubs/lock.svg\" alt=\"Locked\"\n class=\"lock-icon mr-2 margin-bottom-xxs\">\n <div class=\"flex-auto flex flex-col\" style=\"min-width: 0;\">\n <p class=\"margin-remove text-truncate mat-subheading-1 font-bold nodtranslate\"\n [ngClass]=\"{'text-active': pathSet?.has(content.identifier) && isEnrolled}\"\n [matTooltip]=\"content?.name?.length > 50 ? content?.name : ''\"\n matTooltipPosition=\"above\">\n <span>{{isMilestone ? index -1 : index}}. </span>{{ content?.name | truncate:50 }}\n </p>\n <div class=\"mt-1\" *ngIf=\"isMilestone && isMilestoneLocked\">\n <span class=\"locked-text\">Locked</span>\n </div>\n <div class=\"mt-1\" *ngIf=\"content?.isMandatory\">\n <span class=\"mandatory-text mat-caption\">Mandatory</span>\n </div>\n </div>\n \n <div class=\"type-container resource mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Resource'\">\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\n <span class=\"nodtranslate\">Resource</span>\n </div>\n <div class=\"type-container module mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Collection'\">\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\n <span class=\"nodtranslate\">Module</span>\n </div>\n <div class=\"type-container course mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Course'\">\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\n <span class=\"nodtranslate\">Course</span>\n </div>\n </div>\n <!-- Milestone Badge -->\n <div *ngIf=\"isMilestone\" class=\"milestone-badge mt-2 mb-2\">\n <span class=\"milestone-badge-text nodtranslate\">Milestone {{index - 1}}</span>\n </div>\n <!-- Milestone Description (2 lines with ellipsis) -->\n <p #milestoneDescRef *ngIf=\"isMilestone && content?.description\" class=\"milestone-description mt-2 nodtranslate\"\n [matTooltip]=\"isMultiLineTruncated(milestoneDescRef) ? content?.description : ''\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"multiline-tooltip\">\n {{ content?.description }}\n </p>\n <div class=\"flex flex-row gap-3 items-center content-key-values mt-2\">\n <mat-icon *ngIf=\"!isModule\" alt=\"course\"\n class=\"time-icon icon-color\">video_library</mat-icon>\n <img *ngIf=\"isModule\" alt=\"Module\" class=\"time-icon\"\n src=\"/assets/icons/content/grey/module.svg\">\n <div class=\"text-xs nodtranslate\">{{ (hierarchyMapData[content?.identifier]?.duration ||\n 120)|\n pipeDurationTransform: 'hms' }}</div>\n\n <ng-container *ngIf=\"content?.moduleCount\">\n <div class=\"flex items-center\">\n <span class=\"period\"></span>\n </div>\n <div class=\"text-xs nodtranslate\">{{content?.moduleCount}} {{content?.moduleCount > 1?\n 'modules' :\n 'module'}}</div>\n </ng-container>\n <ng-container *ngIf=\"content?.leafNodesCount\">\n <div class=\"flex items-center\">\n <span class=\"period\"></span>\n </div>\n <div class=\"text-xs nodtranslate\">{{content?.leafNodesCount}} {{content?.leafNodesCount\n >1 ? 'items':\n 'item'}}</div>\n </ng-container>\n </div>\n <!-- Milestone Completion Progress -->\n <div *ngIf=\"isMilestone && isEnrolled && !isMilestoneLocked\" class=\"milestone-progress mt-2 flex items-center justify-between\">\n <div>\n <span class=\"milestone-progress-text nodtranslate\">{{getMilestoneCompletedCount()}} of\n {{content?.leafNodesCount || 0}} completed</span>\n </div>\n <!-- View Achievement Button for completed milestones - Outside clickable area -->\n <div *ngIf=\"isMilestone && isEnrolled && (getCompletionPercentage(content?.identifier) >= 100 || getCompletionStatus(content?.identifier) === 2)\"\n class=\"view-achievement-container mt-2\">\n <button type=\"button\" class=\"view-achievement-btn\" [disabled]=\"achievementLoading\"\n (click)=\"viewMilestoneAchievement($event)\">\n <span *ngIf=\"!achievementLoading\">View Achievement</span>\n <mat-spinner *ngIf=\"achievementLoading\" [diameter]=\"16\" \n [strokeWidth]=\"2\" color=\"primary\" class=\"inline-spinner\"></mat-spinner>\n </button>\n </div>\n </div>\n <!-- Unlock Criteria Message for Locked Milestones -->\n <div *ngIf=\"isMilestone && isEnrolled && isMilestoneLocked\" class=\"milestone-locked-message mt-2\">\n <span class=\"locked-criteria-text mat-caption\">\n {{ getMilestoneUnlockMessage() }}\n </span>\n </div>\n \n </div>\n <!-- For course progress to be shown -->\n <ng-container *ngIf=\"isEnrolled && !isMilestoneLocked && !isParentMilestoneLocked\">\n <ng-container\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) && content.primaryCategory === 'Course'\">\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) == 2\">\n <div class=\"flex flex-1\">\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\n <div class=\"flex flex-row justify-end w-full \">\n <span class=\"mat-body-2 nodtranslate \">\n {{getCompletionPercentage(content?.identifier)}}%</span>\n </div>\n\n <ws-widget-content-progress [contentId]=\"content?.progress\"\n [progress]=\"getCompletionPercentage(content?.identifier)\"\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\n </ws-widget-content-progress>\n </div>\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\n <a class=\"ml-5 certificate-btn\"\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\n <span class=\"nodtranslate\">Certificate</span>\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\n class=\"ml-2\">arrow_downward</mat-icon>\n <div class=\"center flex flex-middle certificate-loader\"\n *ngIf=\"downloadCertificateLoading\">\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\n [diameter]=\"16\"></mat-spinner>\n </div>\n </a>\n </ng-container>\n </div>\n <!-- <circle-progress class=\"flex items-center progress\" [percent]=\"100\" [radius]=\"12\"\n [outerStrokeWidth]=\"3\" [innerStrokeWidth]=\"3\" [space]=\"-3\"\n [outerStrokeColor]=\"progressColor()\" [innerStrokeColor]=\"'rgba(0,0,0,.16)'\"\n [animation]=\"true\" [animationDuration]=\"300\" [showTitle]=\"false\" [showUnits]=\"false\"\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\" [backgroundStrokeWidth]=\"3\"\n [showZeroOuterStroke]=false [backgroundPadding]=\"-9\" [startFromZero]=\"false\"\n [backgroundPadding]=\"0\" [imageHeight]=\"24\" [imageWidth]=\"24\" [showBackground]=\"false\"\n [outerStrokeLinecap]=\"'butt'\">\n </circle-progress> -->\n </ng-container>\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\n <div class=\"flex flex-1\">\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\n <div class=\"flex flex-row justify-end w-full ws-mat-black-text\">\n <span class=\"mat-body-2 ws-mat-black-text nodtranslate\">\n {{getCompletionPercentage(content?.identifier)}}%</span>\n </div>\n\n <ws-widget-content-progress [contentId]=\"content?.progress\"\n [progress]=\"getCompletionPercentage(content?.identifier)\"\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\n </ws-widget-content-progress>\n </div>\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\n <a class=\"ml-5 certificate-btn\"\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\n <span class=\"nodtranslate\">Certificate</span>\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\n class=\"ml-2\">arrow_downward</mat-icon>\n <div class=\"center flex flex-middle certificate-loader\"\n *ngIf=\"downloadCertificateLoading\">\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\n [diameter]=\"16\"></mat-spinner>\n </div>\n </a>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n </ng-container>\n\n <div class=\"see-all-container\">\n <a href=\"javascript:void(0)\" role=\"button\"\n (click)=\"content.viewChildren = !content.viewChildren; expandActive = false\"\n class=\"see-all-btn tab custom-chevron customicon\" mat-button>\n <mat-icon *ngIf=\"!content.viewChildren && !isModule\">keyboard_arrow_down</mat-icon>\n <mat-icon *ngIf=\"content.viewChildren && !isModule\">keyboard_arrow_up</mat-icon>\n <mat-icon *ngIf=\"!content.viewChildren && isModule\">add</mat-icon>\n <mat-icon *ngIf=\"content.viewChildren && isModule\">remove</mat-icon>\n </a>\n </div>\n </div>\n </div>\n </div>\n <div class=\"child-wrapper \" *ngIf=\"content.viewChildren\" [ngClass]=\"{'open': content.viewChildren,\n 'close': !content.viewChildren,\n 'course':!isModule,\n 'module': isModule}\" [@panelInOut]>\n <div class=\"children-container\" [ngClass]=\"{'module': isModule, '': !isModule}\">\n <ws-widget-app-toc-content-card-v2 [forPreview]=\"forPreview\" [componentName]=\"componentName\"\n [content]=\"child\" [expandAll]=\"expandAll\" [rootId]=\"rootId\" [batchId]=\"batchId\"\n [rootContentType]=\"rootContentType\" [index]=\"j+1\" [baseContentReadData]=\"baseContentReadData\"\n [pathSet]=\"pathSet\" [hierarchyMapData]=\"hierarchyMapData\" [batchData]=\"batchData\"\n [mlCourse]=\"mlCourse\" [parentMilestoneLocked]=\"isMilestoneLocked || isParentMilestoneLocked\"\n *ngFor=\"let child of content?.children; trackBy: contentTrackBy; let j= index;let isFirst = first\"\n [ngClass]=\"{'moduleCard': checkIsModule(child), 'resourceCard': !checkIsModule(child), 'first': isFirst}\">\n </ws-widget-app-toc-content-card-v2>\n </div>\n </div>\n </ng-container>\n</ng-template>\n\n\n<ng-container *ngIf=\"isPreAssessment\">\n <div class=\"collection-wrapper p-4 flex flex-col position-relative\" [ngClass]=\"{'open': check(content),\n 'course':!isModule, 'module': isModule,\n 'content-active': pathSet?.has(content.identifier)}\">\n <div class=\"card-collection w-auto sm:w-100 padding-right-xl\">\n <!-- <img class=\"card-thumbnail ws-mat-primary-lite-background\" [src]=\"content?.appIcon\" alt=\"Thumbnail\"\n (click)=\"content.viewChildren = !content.viewChildren\" [wsUtilsDefaultThumbnail]=\"defaultThumbnail\" /> -->\n <div class=\"flex flex-col flex-wrap flex-between width-expand pr-0 w-100 \">\n\n <div class=\"text-truncate\" [ngClass]=\"{'cursor-pointer': !isEnabled}\"\n (click)=\"content.viewChildren = !content.viewChildren\">\n <div class=\"flex sm:flex-row flex-wrap\">\n <ng-container>\n <ng-container\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier) ; else elseBlock\">\n\n <ng-container *ngIf=\"getCompletionStatus(content.identifier) == 2\">\n <div class=\"completed mr-2\">\n <div>\n <mat-icon class=\"completed-icon\" [color]=\"blue\">check_circle</mat-icon>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\n\n <circle-progress class=\"flex items-center progress mr-1\"\n [percent]=\"getCompletionPercentage(content?.identifier)\" [radius]=\"10\"\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [space]=\"-2\"\n [outerStrokeColor]=\"progressColor2()\" [innerStrokeColor]=\"'rgba(0, 0, 0, 0.16)'\"\n [animation]=\"true\" [animationDuration]=\"250\" [showTitle]=\"false\"\n [showUnits]=\"false\" [showSubtitle]=\"false\" [showInnerStroke]=\"true\"\n [clockwise]=\"true\" [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\"\n [backgroundStrokeWidth]=\"3\" matTooltip=\"In progress\" [showZeroOuterStroke]=false\n [backgroundPadding]=\"-7\" [startFromZero]=\"false\" [backgroundPadding]=\"0\"\n [imageHeight]=\"18\" [imageWidth]=\"18\" [showBackground]=\"false\"\n [outerStrokeLinecap]=\"'butt'\">\n </circle-progress>\n </ng-container>\n </ng-container>\n <ng-template #elseBlock>\n <circle-progress class=\"flex items-center progress mr-1\" [percent]=\"0\" [radius]=\"11\"\n [outerStrokeWidth]=\"2\" [innerStrokeWidth]=\"2\" [outerStrokeColor]=\"'#808080'\"\n [innerStrokeColor]=\"'#808080'\" [animation]=\"true\" [space]=\"-2\" [showUnits]=\"false\"\n [animationDuration]=\"250\" [showTitle]=\"false\" [backgroundPadding]=\"0\"\n [backgroundPadding]=\"-9\" [outerStrokeLinecap]=\"'butt'\" matTooltip=\"Not started\"\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\n [imageHeight]=\"22\" [imageWidth]=\"22\" [showBackground]=\"false\"></circle-progress>\n </ng-template>\n </ng-container>\n <div [ngClass]=\"{'collection-active-class': pathSet?.has(content?.identifier)}\"></div>\n <!-- <p class=\"margin-remove text-truncate mat-subheading-1 flex-auto font-bold nodtranslate\"\n [ngClass]=\"{'text-active': pathSet?.has(content.identifier)}\">\n {{index}}. {{ content?.name | truncate:50 }}\n </p> -->\n <a class=\"margin-remove text-truncate mat-subheading-1 flex-auto font-bold nodtranslate\"\n [class.disabled]=\"null\" [ngClass]=\"{'ml-3': isEnrolled}\"\n [routerLink]=\"(isAllowed && !forPreview && isEnabled) ? resourceLink.url : null\"\n [queryParams]=\"computedQueryParams\">\n <!-- {{content?.courseCategory}} -->\n <div [ngClass]=\"{'resource-active': pathSet?.has(content?.identifier)}\"></div>\n <div class=\"text-truncate \" [ngClass]=\"{'cursor-pointer': !isEnabled}\"\n (click)=\"raiseTelemetry(); changeResource()\">\n <div class=\"flex flex-col sm:flex-row flex-wrap\">\n <p class=\"margin-remove text-truncate mat-body-2 flex-auto font-bold nodtranslate\"\n [ngClass]=\"{'text-active': pathSet?.has(content?.identifier)}\"\n [matTooltip]=\"content?.name?.length > 50 ? content?.name : ''\"\n matTooltipPosition=\"above\">\n <!-- <mat-icon class=\"margin-right-xs radiobtn time-icon\">radio_button_unchecked </mat-icon> -->\n {{index}}. {{ content?.name | truncate:50 }}\n\n </p>\n <span class=\"content-type optional-span nodtranslate\"\n *ngIf=\"content?.optionalReading\">{{ 'playerbrief.optional' | translate |\n titlecase}} </span>\n </div>\n <!-- for default grey icons -->\n <ng-container *ngIf=\"!pathSet?.has(content?.identifier)\">\n <div class=\"resicons ws-mat-black60-text\">\n <img src=\"/assets/icons/content/grey/video.svg\" alt=\"Video\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\n content?.mimeType ==='application/x-mpegURL'\">\n <img src=\"/assets/icons/content/grey/audio.svg\" alt=\"Audio\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'audio/mpeg'\">\n <img src=\"/assets/icons/content/grey/pdf.svg\" alt=\"PDF\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/pdf'\">\n <!-- <img src=\"/assets/icons/content/grey/resource.svg\" alt=\"Survey\" class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/survey'\"> -->\n <img src=\"/assets/icons/content/grey/link.svg\" alt=\"InteractiveContent\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\n <img src=\"/assets/icons/content/grey/assessment.svg\" alt=\"Assessment\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\n <img src=\"/assets/icons/content/grey/content_copy.svg\" class=\"contenticon\"\n alt=\"Course\"\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\n <img src=\"/assets/icons/content/grey/module.svg\"\n class=\"float-left margin-right-xs\" alt=\"offline sessions\"\n *ngIf=\"content.mimeType === 'application/offline'\">\n\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\n\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{\n content?.maxQuestions }} {{ 'playerbrief.questions' | translate |\n titlecase}}</span>\n </ng-container>\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\n <span class=\"resourceDuration ws-mat-black60-text nodtranslate\">{{\n (content?.duration||\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\n pipeDurationTransform:\n 'hms'\n }}</span>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- for white icons when content highlighted -->\n <ng-container *ngIf=\"pathSet?.has(content?.identifier)\">\n <div class=\"resicons ws-mat-white-text\">\n <img src=\"/assets/icons/content/white/video.svg\" alt=\"Video\"\n class=\"float-left margin-right-xs\" *ngIf=\"content?.mimeType === 'video/mp4' || content?.mimeType === 'video/x-youtube' ||\n content?.mimeType ==='application/x-mpegURL'\">\n <img src=\"/assets/icons/content/white/audio.svg\" alt=\"Audio\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'audio/mpeg'\">\n <img src=\"/assets/icons/content/white/pdf.svg\" alt=\"PDF\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/pdf'\">\n <!-- <img src=\"/assets/icons/content/white/resource.svg\" alt=\"Survey\" class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/survey'\"> -->\n <img src=\"/assets/icons/content/white/link.svg\" alt=\"InteractiveContent\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/vnd.ekstep.html-archive' || content?.mimeType === 'text/x-url'\">\n <img src=\"/assets/icons/content/white/assessment.svg\" alt=\"Assessment\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'application/json' || content?.mimeType === 'application/quiz' || content?.mimeType === 'application/vnd.sunbird.questionset'\">\n <img src=\"/assets/icons/content/grey/image.svg\" alt=\"Image\"\n class=\"float-left margin-right-xs\"\n *ngIf=\"content?.mimeType === 'image/png' || content?.mimeType === 'image/jpeg'\">\n <img src=\"/assets/icons/content/white/content_copy.svg\" class=\"contenticon\"\n alt=\"Course\"\n *ngIf=\"content.mimeType === 'application/vnd.ekstep.content-collection' || content?.mimeType === 'application/survey'\">\n <img src=\"/assets/icons/content/white/module.svg\"\n class=\"float-left margin-right-xs\" alt=\"offline sessions\"\n *ngIf=\"content.mimeType === 'application/offline'\">\n <ng-container *ngIf=\"content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE\">\n <span class=\"resourceDuration ws-mat-white-text nodtranslate\">{{\n content?.maxQuestions }} {{ 'playerbrief.questions' | translate |\n titlecase}}</span>\n </ng-container>\n <ng-container *ngIf=\"!(content.primaryCategory === primaryCategory.FINAL_ASSESSMENT ||\n content.primaryCategory === primaryCategory.COMP_ASSESSMENT ||\n content.primaryCategory === primaryCategory.STANDALONE_ASSESSMENT ||\n content.primaryCategory === primaryCategory.PRACTICE_RESOURCE)\">\n <span class=\"resourceDuration ws-mat-white-text nodtranslate\">{{\n (content?.duration||\n hierarchyMapData[content?.identifier]?.expectedDuration || 0)|\n pipeDurationTransform:\n 'hms'\n }}</span>\n </ng-container>\n </div>\n </ng-container>\n </div>\n </a>\n <!-- <div class=\"type-container resource mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Resource'\">\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\n <span class=\"nodtranslate\">Resource</span>\n </div>\n <div class=\"type-container module mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Collection'\">\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\n <span class=\"nodtranslate\">Module</span>\n </div>\n <div class=\"type-container course mt-2 sm:mt-0\" *ngIf=\"content?.category === 'Course'\">\n <mat-icon class=\"mr-1 custom-icon rotate-90\">call_to_action</mat-icon>\n <span class=\"nodtranslate\">Course</span>\n </div> -->\n </div>\n\n </div>\n <!-- For course progress to be shown -->\n <ng-container>\n <ng-container\n *ngIf=\"!forPreview && content?.identifier && getCompletionPercentage(content?.identifier)\">\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) == 2\">\n <div class=\"flex flex-1\">\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\n <div class=\"flex flex-row justify-end w-full \">\n <span class=\"mat-body-2 nodtranslate \">\n {{getCompletionPercentage(content?.identifier)}}%</span>\n </div>\n\n <ws-widget-content-progress [contentId]=\"content?.progress\"\n [progress]=\"getCompletionPercentage(content?.identifier)\"\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\n </ws-widget-content-progress>\n </div>\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\n <a class=\"ml-5 certificate-btn\"\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\n <span class=\"nodtranslate\">Certificate</span>\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\n class=\"ml-2\">arrow_downward</mat-icon>\n <div class=\"center flex flex-middle certificate-loader\"\n *ngIf=\"downloadCertificateLoading\">\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\n [diameter]=\"16\"></mat-spinner>\n </div>\n </a>\n </ng-container>\n </div>\n <!-- <circle-progress class=\"flex items-center progress\" [percent]=\"100\" [radius]=\"12\"\n [outerStrokeWidth]=\"3\" [innerStrokeWidth]=\"3\" [space]=\"-3\"\n [outerStrokeColor]=\"progressColor()\" [innerStrokeColor]=\"'rgba(0,0,0,.16)'\"\n [animation]=\"true\" [animationDuration]=\"300\" [showTitle]=\"false\" [showUnits]=\"false\"\n [showSubtitle]=\"false\" [showInnerStroke]=\"true\" [clockwise]=\"true\"\n [backgroundOpacity]=\"0\" [backgroundGradient]=\"false\" [backgroundStrokeWidth]=\"3\"\n [showZeroOuterStroke]=false [backgroundPadding]=\"-9\" [startFromZero]=\"false\"\n [backgroundPadding]=\"0\" [imageHeight]=\"24\" [imageWidth]=\"24\" [showBackground]=\"false\"\n [outerStrokeLinecap]=\"'butt'\">\n </circle-progress> -->\n </ng-container>\n <ng-container *ngIf=\"getCompletionStatus(content?.identifier) < 2\">\n <div class=\"flex flex-1\">\n <div class=\"mt-2 mr-4 flex flex-1 flex-col progress-container\">\n <div class=\"flex flex-row justify-end w-full ws-mat-black-text\">\n <span class=\"mat-body-2 ws-mat-black-text nodtranslate\">\n {{getCompletionPercentage(content?.identifier)}}%</span>\n </div>\n\n <ws-widget-content-progress [contentId]=\"content?.progress\"\n [progress]=\"getCompletionPercentage(content?.identifier)\"\n [progressType]=\"'percentage'\" [customClassName]=\"'viewer-progress'\">\n </ws-widget-content-progress>\n </div>\n <ng-container *ngIf=\"content?.issuedCertificatesId\">\n <a class=\"ml-5 certificate-btn\"\n [ngClass]=\"{'disable-btn': downloadCertificateLoading || content?.issuedCertificatesId}\"\n (click)=\"!downloadCertificateLoading && downloadCertificate(content?.issuedCertificatesId);$event.stopPropagation()\">\n <!-- <img src=\"fusion-assets/images/certificate-ico.svg\" width=\"24\" height=\"24\"> -->\n <span class=\"nodtranslate\">Certificate</span>\n <mat-icon *ngIf=\"!downloadCertificateLoading\"\n class=\"ml-2\">arrow_downward</mat-icon>\n <div class=\"center flex flex-middle certificate-loader\"\n *ngIf=\"downloadCertificateLoading\">\n <mat-spinner strokeWidth=\"2\" stroke=\"'white'\" class=\"white-spinner\"\n [diameter]=\"16\"></mat-spinner>\n </div>\n </a>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n </ng-container>\n\n <!-- <div class=\"see-all-container\">\n <a href=\"javascript:void(0)\" role=\"button\"\n (click)=\"content.viewChildren = !content.viewChildren; expandActive = false\"\n class=\"see-all-btn tab custom-chevron customicon\" mat-button>\n <mat-icon *ngIf=\"!content.viewChildren && !isModule\">keyboard_arrow_down</mat-icon>\n <mat-icon *ngIf=\"content.viewChildren && !isModule\">keyboard_arrow_up</mat-icon>\n <mat-icon *ngIf=\"!content.viewChildren && isModule\">add</mat-icon>\n <mat-icon *ngIf=\"content.viewChildren && isModule\">remove</mat-icon>\n </a>\n </div> -->\n </div>\n </div>\n </div>\n\n</ng-container>", styles: [".customicon{position:absolute;top:-.5em;right:0}.customicon .mat-icon{color:#1a4ca1}a.disabled{pointer-events:none;cursor:default}span.optional-span{margin-left:8px;padding:0 6px;border-radius:2px;display:inline-block;background-color:#0074b6;color:#fff;font-size:12px}.card-collection{display:flex;align-items:center;border-radius:8px}.card-collection .card-thumbnail{height:100%;margin-right:12px;cursor:pointer;border-radius:8px 0 0}@media only screen and (max-width: 469px){.card-collection{flex-direction:column;align-items:flex-start!important}.card-collection .card-thumbnail{height:100%!important;width:100%!important}.card-collection .text-truncate{white-space:unset!important}}.tab:focus{outline:1px solid!important}.custom-chevron:focus{outline:0px solid!important}.resource-container{display:flex;align-items:flex-start;flex-direction:column}.resource-container .resource{padding:16px 16px 16px 0;width:100%}.resource-container .card-thumbnail{height:100%;cursor:pointer}.resource-container .img-container{position:relative;margin-right:12px}.resource-container .img-container ws-widget-content-progress{position:absolute;left:0;right:0;bottom:5px}@media only screen and (max-width: 469px){.resource-container{flex-direction:column;align-items:flex-start!important}.resource-container .card-thumbnail{height:100%!important;width:100%!important}.resource-container .text-truncate{white-space:unset!important}}.child-meta-container{margin-top:8px;display:flex}.child-meta-container .child-structure{display:flex;align-items:center;flex-wrap:wrap}.child-meta-container .child-structure span{margin-right:12px;text-align:center;margin-bottom:8px}.child-meta-container .child-structure .structure-icon{margin-right:12px}@media only screen and (max-width: 469px){.child-meta-container{margin-left:.5rem;justify-content:space-between}}.resource-container{display:flex;align-items:center}.resource-container ws-display-content-type-icon{display:flex;align-items:center}.resource-container .resource-meta{margin-left:12px;display:flex;justify-content:space-between;align-items:center}.completed-icon{color:#1a4ca1}.collection-wrapper{padding:1rem}.collection-wrapper.course.content-active{background-color:#1a4ca1;color:#fff}.collection-wrapper.course.content-active .period{background:#fff}.collection-wrapper.course.content-active .text-active,.collection-wrapper.course.content-active .icon-color,.collection-wrapper.course.content-active .customicon .mat-icon{color:#fff}.collection-wrapper.course.content-active .progress-container span{color:#fff!important}.collection-wrapper.course.content-active .milestone-description,.collection-wrapper.course.content-active .milestone-progress-text{color:#fff}.text-active{color:#1a4ca1}.text-active.font-bold{font-weight:600}.activeResource{background-color:#1a4ca1;color:#fff;padding-top:1rem!important;padding-bottom:1rem!important}.activeResource .text-active{color:#fff}.activeResource .text-active.font-bold{font-weight:600}.activeResource .resourceDuration,.activeResource .completed-icon{color:#fff}.collection-wrapper.open{border-bottom:1px solid rgba(0,0,0,.16)}.collection-wrapper.close{border:none}.child-wrapper.open{border-radius:0 0 8px 8px}.children-container .mat-subheading-1{font:500 16px/24px Lato!important}.children-container .resource-container{margin-bottom:16px}.children-container .resource-container .resource{padding:0}.children-container .resource-container .card-thumbnail{height:65px;align-self:center}.first.resourceCard:nth-child(1) .resource{margin-top:16px!important}.first.resourceCard:nth-child(1) .activeResource{margin-top:0!important}.children-container .resourceCard:last-child .resource-container:has(.activeResource){margin-bottom:0!important}.moduleCard:not(:last-child)>.collection-wrapper.close.module{border-bottom:4px solid rgba(0,0,0,.08);border-radius:0}.moduleCard:not(:last-child)>.collection-wrapper.open.module+.child-wrapper.open{border-bottom:4px solid rgba(0,0,0,.08);border-radius:0}.collection-wrapper.open.course+.child-wrapper.open .collection-wrapper.open.module+.child-wrapper.open{background-color:#eff3f9;border-bottom:4px solid rgba(0,0,0,.08);border-radius:0}.collection-wrapper.open.module+.child-wrapper.open{background-color:#eff3f9;border-radius:0;padding-bottom:8px}.content-heading{letter-spacing:0px;color:#222}.content-type{letter-spacing:0px}.time-icon{height:16px;width:16px;font-size:16px;vertical-align:middle}.time-icon.icon-color{color:#0009}.period{width:3px;height:3px;background:#0009;border-radius:4px}.time-value{letter-spacing:0px;color:#222;text-transform:lowercase}.see-all-container{position:absolute;right:16px;top:24px}.oval-white{background:#fff 0% 0% no-repeat padding-box;border-radius:8px;padding:2px 8px}.type-container{letter-spacing:0px;display:flex;align-items:center}.type-container .rotate-90{transform:rotate(-90deg)}.type-container .custom-icon{width:18px;height:18px;font-size:18px;margin-right:8px}.type-container.resource{color:#00a9f4}.type-container.module{color:#34d6a4}.type-container.course{color:#f58634}.no-mb{margin-bottom:0!important}.w-100{width:100%}.w-auto{width:auto}.progress-bar-thin{height:5px!important}.progress-bar-thin ::ng-deep .mat-progress-bar{height:5px}.progress-bar-thin ::ng-deep .theme-igot.day-mode .mat-progress-bar-buffer{background-color:transparent!important}.progress-bar-thin ::ng-deep .theme-igot.day-mode .mat-progress-bar-background{fill:transparent}.radiobtn{color:#00000029}.resicons img{width:22px;opacity:.5;margin-top:2px;vertical-align:sub}.certificate-btn{height:24px;background:#1a4ca1;display:flex;justify-content:center;align-items:center;padding:4px 11px;color:#fff;border-radius:20px;border:1px solid white;font:400 12px/16px Lato;cursor:pointer}.certificate-btn .mat-icon{fill:#fff;color:#fff;font-size:16px;height:auto;width:auto}.view-certificate-wrapper{display:flex;border-radius:4px;border:1.5px solid rgb(0,116,182);opacity:1;padding:8px}.collection-wrapper.course,.collection-wrapper.module,.resource-container .resource{padding-left:16px;box-sizing:border-box;width:100%;overflow:hidden}.children-container.module .resource-container .resource,.course .collection-wrapper.module{padding-left:24px;box-sizing:border-box;width:100%}.course .children-container.module .resource-container .resource{padding-left:32px;box-sizing:border-box;width:100%}.course .resource-container .resource{padding-left:24px}::ng-deep .white-spinner{stroke:#fff!important}.certificate-loader ::ng-deep .mat-progress-spinner circle,.mat-spinner circle{stroke:#fff}.lock-message{background:#fff4ec;color:#d13924;padding:10px;border-radius:4px;display:block!important;width:100%}.content-locking{padding:8px 12px;margin-top:8px;margin-left:0;margin-right:0;border-radius:4px;background:#fff4ec;display:flex!important;align-items:center;gap:8px;width:100%;box-sizing:border-box}.lock-icon{color:#f3962f;font-size:20px;flex-shrink:0}.unlock-message{background:#efffec;color:#0c9600;padding:10px}.unlock-icon{color:#0c9600}.download-btn{padding:4px 12px;text-underline-position:from-font;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none;cursor:pointer;border-radius:40px;color:#1b4ca1;font-weight:700;border:1px solid #1B4CA1;display:inline-block;pointer-events:auto;position:relative;z-index:1}.activeResource .download-btn.active{color:#fff;border:1px solid #fff}.milestone-badge{display:inline-block;background-color:#fefaf4;border:1px solid #EF951E;border-radius:16px;padding:2px 12px}.milestone-badge-text{font-size:12px;font-weight:500;color:#212121}.milestone-description{font-size:14px;line-height:1.5;color:#000000b3;margin:0;display:-webkit-box!important;-webkit-line-clamp:2!important;-webkit-box-orient:vertical!important;overflow:hidden!important;text-overflow:ellipsis!important;word-break:break-word!important;white-space:normal!important;max-width:100%!important}.milestone-progress{display:flex;align-items:center}.milestone-progress-text{font-size:14px;font-weight:500;color:#0009}.milestone-locked-message{display:flex;align-items:center;padding:8px 12px;background-color:#f3962f1a;border-left:3px solid #F3962F;border-radius:4px}.locked-criteria-text{font-size:13px;font-weight:400;color:#000000b3;line-height:1.4}.locked-text{font-size:14px;font-weight:500;color:#f3962f}.mandatory-text{color:#d13924!important}.view-achievement-container{display:flex;align-items:center}.view-achievement-btn{background-color:transparent;border:1.5px solid #1a4ca1;color:#1a4ca1;border-radius:20px;padding:6px 16px;font-size:14px;font-weight:500;cursor:pointer;display:flex;align-items:center;gap:8px;transition:all .2s ease;min-width:150px}.view-achievement-btn:hover:not(:disabled){background-color:#1a4ca1;color:#fff}.view-achievement-btn:disabled{opacity:.6;cursor:not-allowed}.view-achievement-btn .inline-spinner{display:inline-block}::ng-deep .multiline-tooltip{white-space:pre-wrap!important;max-width:400px!important;word-break:break-word!important;line-height:1.4!important}\n"] }]
1169
+ }], ctorParameters: function () { return [{ type: i1.EventService }, { type: i2.MatLegacyDialog }, { type: i0.Renderer2 }, { type: i3.CertificateService }, { type: i4.AppTocService }, { type: i5.ContentLanguageService }, { type: i6.ResourceDownloadHelperService }, { type: i1.ConfigurationsService }, { type: i7.MatLegacySnackBar }]; }, propDecorators: { content: [{
1170
+ type: Input
1171
+ }], expandAll: [{
1172
+ type: Input
1173
+ }], rootId: [{
1174
+ type: Input
1175
+ }], rootContentType: [{
1176
+ type: Input
1177
+ }], forPreview: [{
1178
+ type: Input
1179
+ }], batchId: [{
1180
+ type: Input
1181
+ }], componentName: [{
1182
+ type: Input
1183
+ }], index: [{
1184
+ type: Input
1185
+ }], pathSet: [{
1186
+ type: Input
1187
+ }], expandActive: [{
1188
+ type: Input
1189
+ }], hierarchyMapData: [{
1190
+ type: Input
1191
+ }], batchData: [{
1192
+ type: Input
1193
+ }], isPreAssessment: [{
1194
+ type: Input
1195
+ }], baseContentReadData: [{
1196
+ type: Input
1197
+ }], mlCourse: [{
1198
+ type: Input
1199
+ }], parentMilestoneLocked: [{
1200
+ type: Input
1201
+ }] } });
1202
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLXRvYy1jb250ZW50LWNhcmQtdjIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicmFyeS9zdW5iaXJkLWNiL3RvYy9zcmMvbGliL19jb2xsZWN0aW9uL19jb21tb24vY29udGVudC10b2MvYXBwLXRvYy1jb250ZW50LWNhcmQtdjIvYXBwLXRvYy1jb250ZW50LWNhcmQtdjIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicmFyeS9zdW5iaXJkLWNiL3RvYy9zcmMvbGliL19jb2xsZWN0aW9uL19jb21tb24vY29udGVudC10b2MvYXBwLXRvYy1jb250ZW50LWNhcmQtdjIvYXBwLXRvYy1jb250ZW50LWNhcmQtdjIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQStDLE1BQU0sZUFBZSxDQUFBO0FBQzdGLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQTtBQUN0RSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQTtBQUU5RSxPQUFPLEVBQWdCLFFBQVEsRUFBeUIsTUFBTSxzQkFBc0IsQ0FBQTtBQUNwRixPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSx1REFBdUQsQ0FBQTtBQUVsRyxPQUFPLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUE7QUFDekUsbUJBQW1CO0FBQ25CLE9BQU8sQ0FBQyxNQUFNLFFBQVEsQ0FBQTtBQUN0QixPQUFPLE1BQU0sTUFBTSxRQUFRLENBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUF3QjNCLE1BQU0sT0FBTyw0QkFBNEI7SUE0RHZDLFlBQ1UsTUFBb0IsRUFDcEIsTUFBaUIsRUFDakIsUUFBbUIsRUFDbkIsa0JBQXNDLEVBQ3RDLFNBQXdCLEVBQ3hCLGNBQXNDLEVBQ3RDLHlCQUF3RCxFQUN4RCxTQUFnQyxFQUNoQyxRQUFxQjtRQVJyQixXQUFNLEdBQU4sTUFBTSxDQUFjO1FBQ3BCLFdBQU0sR0FBTixNQUFNLENBQVc7UUFDakIsYUFBUSxHQUFSLFFBQVEsQ0FBVztRQUNuQix1QkFBa0IsR0FBbEIsa0JBQWtCLENBQW9CO1FBQ3RDLGNBQVMsR0FBVCxTQUFTLENBQWU7UUFDeEIsbUJBQWMsR0FBZCxjQUFjLENBQXdCO1FBQ3RDLDhCQUF5QixHQUF6Qix5QkFBeUIsQ0FBK0I7UUFDeEQsY0FBUyxHQUFULFNBQVMsQ0FBdUI7UUFDaEMsYUFBUSxHQUFSLFFBQVEsQ0FBYTtRQXBFdEIsWUFBTyxHQUE4QixJQUFJLENBQUE7UUFDekMsY0FBUyxHQUFHLEtBQUssQ0FBQTtRQUdqQixlQUFVLEdBQUcsS0FBSyxDQUFBO1FBRWxCLGtCQUFhLEdBQVcsS0FBSyxDQUFBO1FBRzdCLGlCQUFZLEdBQUcsSUFBSSxDQUFBO1FBQ25CLHFCQUFnQixHQUFRLEVBQUUsQ0FBQTtRQUMxQixjQUFTLEdBQWtELElBQUksQ0FBQTtRQUMvRCxvQkFBZSxHQUFHLEtBQUssQ0FBQTtRQUN2Qix3QkFBbUIsR0FBOEIsSUFBSSxDQUFBO1FBQ3JELGFBQVEsR0FBOEIsSUFBSSxDQUFBO1FBQzFDLDBCQUFxQixHQUFHLEtBQUssQ0FBQSxDQUFDLG9EQUFvRDtRQUMzRix3QkFBbUIsR0FBRyxLQUFLLENBQUE7UUFDM0IsK0JBQTBCLEdBQUcsS0FBSyxDQUFBO1FBQ2xDLHFCQUFnQixHQUFHLFNBQVMsQ0FBQyxvQkFBb0IsQ0FBQTtRQUNqRCxxQkFBZ0IsR0FBMkI7WUFDekMsVUFBVSxFQUFFLENBQUM7WUFDYixTQUFTLEVBQUUsQ0FBQztZQUNaLE1BQU0sRUFBRSxDQUFDO1lBQ1QsT0FBTyxFQUFFLENBQUM7WUFDVixnQkFBZ0IsRUFBRSxDQUFDO1lBQ25CLGNBQWMsRUFBRSxDQUFDO1lBQ2pCLEtBQUssRUFBRSxDQUFDO1lBQ1IsR0FBRyxFQUFFLENBQUM7WUFDTixNQUFNLEVBQUUsQ0FBQztZQUNULE9BQU8sRUFBRSxDQUFDO1lBQ1YsWUFBWSxFQUFFLENBQUM7WUFDZixJQUFJLEVBQUUsQ0FBQztZQUNQLEtBQUssRUFBRSxDQUFDO1lBQ1IsU0FBUyxFQUFFLENBQUM7WUFDWixPQUFPLEVBQUUsQ0FBQztZQUNWLE9BQU8sRUFBRSxDQUFDO1lBQ1Ysa0JBQWtCLEVBQUUsQ0FBQztZQUNyQixjQUFjLEVBQUUsQ0FBQztTQUNsQixDQUFBO1FBQ0QscUJBQWdCLEdBQUcsRUFBRSxDQUFBO1FBQ3JCLGlCQUFZLEdBQUcsS0FBSyxDQUFBO1FBQ3BCLG9CQUFlLEdBQUcsU0FBUyxDQUFDLGdCQUFnQixDQUFBO1FBQzVDLDJCQUFzQixHQUF3QixJQUFJLENBQUE7UUFDbEQsK0JBQTBCLEdBQXdCLElBQUksQ0FBQTtRQUN0RCx1QkFBa0IsR0FBWSxLQUFLLENBQUE7UUFDbkMsMERBQTBEO1FBQ2xELHdCQUFtQixHQUFZLEtBQUssQ0FBQTtRQUNwQyxvQkFBZSxHQUFZLEtBQUssQ0FBQTtRQUNoQyxzQkFBaUIsR0FBWSxLQUFLLENBQUE7UUFDbEMsdUJBQWtCLEdBQVksS0FBSyxDQUFBO1FBQ25DLDZCQUF3QixHQUFZLEtBQUssQ0FBQTtRQUN6QyxtQ0FBOEIsR0FBWSxLQUFLLENBQUE7UUFDL0MsNkJBQXdCLEdBQVksSUFBSSxDQUFBO1FBQ3hDLGtDQUE2QixHQUFZLEtBQUssQ0FBQTtRQUM5QyxpQ0FBNEIsR0FBWSxLQUFLLENBQUE7UUFDN0MsdUNBQWtDLEdBQVksS0FBSyxDQUFBO1FBQ25ELHdCQUFtQixHQUF5RCxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsV0FBVyxFQUFFLEVBQUUsRUFBRSxDQUFBO1FBQ3hHLHNCQUFpQixHQUFZLEtBQUssQ0FBQTtJQVl0QyxDQUFDO0lBRUwsUUFBUTtRQUNOLElBQUksQ0FBQyxrQ0FBa0MsRUFBRSxDQUFBO1FBQ3pDLElBQUksQ0FBQyw0QkFBNEIsRUFBRSxDQUFBO1FBQ25DLHNDQUFzQztRQUN0Qyx3RUFBd0U7UUFDeEUsTUFBTTtRQUNOLElBQUk7UUFDSixJQUFJLENBQUMsY0FBYyxFQUFFLENBQUE7UUFFckIsb0ZBQW9GO1FBQ3BGLElBQUksQ0FBQywwQkFBMEIsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRTtZQUNwRixJQUFJLE1BQU0sSUFBSSxNQUFNLENBQUMsT0FBTyxFQUFFO2dCQUM1QixPQUFPLENBQUMsR0FBRyxDQUFDLHdEQUF3RCxFQUFFLElBQUksQ0FBQyxPQUFPLEVBQUUsVUFBVSxDQUFDLENBQUE7Z0JBQy9GLDhFQUE4RTtnQkFDOUUsbUZBQW1GO2dCQUNuRixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQTtnQkFDdEMsSUFBSSxDQUFDLDBCQUEwQixFQUFFLENBQUE7YUFDbEM7UUFDSCxDQUFDLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFFRDs7O09BR0c7SUFDSyw0QkFBNEI7UUFDbEMsSUFBSSxDQUFDLDBCQUEwQixFQUFFLENBQUE7SUFDbkMsQ0FBQztJQUVEOztPQUVHO0lBQ0ssMEJBQTBCO1FBQ2hDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ2pCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxLQUFLLENBQUE7WUFDOUIsT0FBTTtTQUNQO1FBRUQsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUE7UUFDekMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixJQUFJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsQ0FBQTtRQUUxRSx3REFBd0Q7UUFDeEQsSUFBSSxRQUFRLEVBQUU7WUFDWixJQUFJLENBQUMsbUJBQW1CLEdBQUcsUUFBUSxDQUFDLFlBQVksS0FBSyxTQUFTLENBQUMsQ0FBQztnQkFDOUQsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEtBQUssU0FBUyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUE7WUFDbkYsSUFBSSxDQUFDLGVBQWUsR0FBRyxRQUFRLENBQUMsUUFBUSxLQUFLLFNBQVMsQ0FBQyxDQUFDO2dCQUN0RCxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsS0FBSyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFBO1lBQ3hGLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxRQUFRLENBQUMsVUFBVSxLQUFLLFNBQVMsQ0FBQyxDQUFDO2dCQUMxRCxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQTtZQUNoRCxJQUFJLENBQUMsa0JBQWtCLEdBQUcsUUFBUSxDQUFDLFdBQVcsS0FBSyxTQUFTLENBQUMsQ0FBQztnQkFDNUQsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUE7WUFDbEQsSUFBSSxDQUFDLHdCQUF3QixHQUFHLFFBQVEsQ0FBQyxnQkFBZ0IsS0FBSyxTQUFTLENBQUMsQ0FBQztnQkFDdkUsUUFBUSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQTtZQUM3RCxJQUFJLENBQUMsOEJBQThCLEdBQUcsUUFBUSxDQUFDLHVCQUF1QixLQUFLLFNBQVMsQ0FBQyxDQUFDO2dCQUNwRixRQUFRLENBQUMsdUJBQXVCLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyw4QkFBOEIsRUFBRSxDQUFBO1NBQzNFO2FBQU07WUFDTCwwREFBMEQ7WUFDMUQsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxLQUFLLFNBQVMsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFBO1lBQ3BGLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQTtZQUN6RixJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUE7WUFDakQsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFBO1lBQ25ELElBQUksQ0FBQyx3QkFBd0IsR0FBRyxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQTtZQUMvRCxJQUFJLENBQUMsOEJBQThCLEdBQUcsSUFBSSxDQUFDLDhCQUE4QixFQUFFLENBQUE7U0FDNUU7UUFFRCxJQUFJLENBQUMsNkJBQTZCLEdBQUcsSUFBSSxDQUFDLDZCQUE2QixFQUFFLENBQUE7UUFDekUsSUFBSSxDQUFDLHdCQUF3QixHQUFHLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFBO1FBQy9ELElBQUksQ0FBQyw0QkFBNEIsR0FBRyxJQUFJLENBQUMsNEJBQTRCLEVBQUUsQ0FBQTtRQUN2RSxJQUFJLENBQUMsa0NBQWtDLEdBQUcsSUFBSSxDQUFDLGtDQUFrQyxFQUFFLENBQUE7UUFDbkYsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFBO1FBQ3JELElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUE7SUFDL0IsQ0FBQztJQUVPLGlCQUFpQjtRQUN2QixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU87WUFBRSxPQUFPLEtBQUssQ0FBQTtRQUMvQixPQUFPLENBQ0wsSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLFFBQVE7WUFDcEUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLGlCQUFpQjtZQUM3RSxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsS0FBSyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsZ0JBQWdCO1lBQzVFLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxLQUFLLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxlQUFlLENBQzVFLENBQUE7SUFDSCxDQUFDO0lBRU8sa0JBQWtCO1FBQ3hCLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU8sS0FBSyxDQUFBO1FBQy9CLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBeUIsQ0FBQTtRQUN6RCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGNBQXdCLENBQUE7UUFDdkQsT0FBTyxVQUFVLEtBQUssV0FBVyxJQUFJLFNBQVMsS0FBSyxXQUFXLENBQUE7SUFDaEUsQ0FBQztJQUVPLDZCQUE2QjtRQUNuQyxJQUFJLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLGdCQUFnQixJQUFJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQzlHLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFBO1lBQzdELE9BQU8sVUFBVSxJQUFJLFVBQVUsQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLGVBQWU7Z0JBQzVGLFVBQVUsQ0FBQyxrQkFBa0IsSUFBSSxDQUFDO2dCQUNsQyxVQUFVLENBQUMsa0JBQWtCLEtBQUssU0FBUyxDQUFDLG1CQUFtQixDQUFDLHNCQUFzQixDQUFBO1NBQ3pGO1FBQ0QsT0FBTyxLQUFLLENBQUE7SUFDZCxDQUFDO0lBRU8sd0JBQXdCO1FBQzlCLElBQUksSUFBSSxDQUFDLDZCQUE2QixFQUFFO1lBQ3RDLElBQUksSUFBSSxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsZ0JBQWdCLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUU7Z0JBQzlHLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFBO2dCQUM3RCxJQUFJLGtCQUFrQixHQUFVLEVBQUUsQ0FBQTtnQkFDbEMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFTLEVBQUUsRUFBRTtvQkFDekMsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxFQUFFO3dCQUN4RCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUE7d0JBQzdDLElBQUksU0FBUyxJQUFJLFNBQVMsQ0FBQyxnQkFBZ0IsS0FBSyxDQUFDLEVBQUU7NEJBQ2pELGtCQUFrQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQTt5QkFDbkM7cUJBQ0Y7Z0JBQ0gsQ0FBQyxDQUFDLENBQUE7Z0JBQ0YsT0FBTyxrQkFBa0IsQ0FBQyxNQUFNLElBQUksVUFBVSxDQUFDLGNBQWMsR0FBRyxDQUFDLENBQUE7YUFDbEU7WUFDRCxPQUFPLEtBQUssQ0FBQTtTQUNiO1FBQ0QsT0FBTyxJQUFJLENBQUE7SUFDYixDQUFDO0lBRU8sbUJBQW1CO1FBQ3pCLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNoQixJQUFJLFFBQVEsR0FBUSxFQUFFLENBQUE7WUFDdEIsSUFBSSxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxLQUFLLDBCQUEwQjtnQkFDNUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEtBQUssMkNBQTJDLEVBQ3JFO2dCQUNBLFFBQVEsR0FBRyxxQ0FBcUMsQ0FBQTtnQkFDaEQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEdBQUcsU0FBUyxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQTthQUM5RDtpQkFBTTtnQkFDTCxRQUFRLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUE7YUFDakM7WUFDRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUE7WUFDM0csT0FBTyxvQkFBb0IsQ0FDekIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQ3ZCLFFBQVEsRUFDUixJQUFJLENBQUMsbUJBQW1CLEVBQUUsVUFBVSxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQ25ELElBQUksQ0FBQyxtQkFBbUIsRUFBRSxXQUFXLElBQUksSUFBSSxDQUFDLGVBQWUsRUFDN0QsSUFBSSxDQUFDLFVBQVUsRUFDZixJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFDNUIsSUFBSSxDQUFDLE9BQU8sRUFDWixJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksSUFBSSxJQUFJLENBQUMsbUJBQW1CLEVBQUUsSUFBSSxFQUNwRCxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUNuRCxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUN4RCxDQUFBO1NBQ0Y7UUFDRCxPQUFPLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxXQUFXLEVBQUUsRUFBRSxFQUFFLENBQUE7SUFDckMsQ0FBQztJQUVPLHdCQUF3QjtRQUM5Qiw0REFBNEQ7UUFDNUQsSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsSUFBSSxJQUFJLENBQUMsbUJBQW1CLENBQUMsY0FBYyxLQUFLLGtCQUFrQixFQUFFO1lBQy9GLE9BQU8sS0FBSyxDQUFBO1NBQ2I7UUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNqQixPQUFPLEtBQUssQ0FBQTtTQUNiO1FBRUQsMENBQTBDO1FBQzFDLElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsRUFBRTtZQUMxRCxPQUFPLEtBQUssQ0FBQTtTQUNiO1FBRUQscUZBQXFGO1FBQ3JGLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQTtRQUN4RixPQUFPLENBQUMsR0FBRyxDQUFDLGdDQUFnQyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsS0FBSyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksSUFBSSxFQUFFO1lBQzdGLFFBQVE7WUFDUixnQkFBZ0IsRUFBRSxRQUFRLEVBQUUsZ0JBQWdCO1lBQzVDLGVBQWUsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVE7U0FDdkMsQ0FBQyxDQUFBO1FBRUYsSUFBSSxRQUFRLElBQUksUUFBUSxDQUFDLGdCQUFnQixLQUFLLFNBQVMsRUFBRTtZQUN2RCxPQUFPLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQTtTQUNqQztRQUVELHdFQUF3RTtRQUN4RSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxLQUFLLEtBQUssRUFBRTtZQUNuQyxPQUFPLEtBQUssQ0FBQTtTQUNiO1FBRUQsMEVBQTBFO1FBQzFFLHlFQUF5RTtRQUN6RSxPQUFPLElBQUksQ0FBQTtJQUNiLENBQUM7SUFFTyw4QkFBOEI7UUFDcEMsSUFBSSxJQUFJLENBQUMscUJBQXFCLEVBQUU7WUFDOUIsT0FBTyxJQUFJLENBQUE7U0FDWjtRQUVELElBQUksQ0FBQyxJQUFJLENBQUMsbUJBQW1CLElBQUksSUFBSSxDQUFDLG1CQUFtQixDQUFDLGNBQWMsS0FBSyxrQkFBa0IsRUFBRTtZQUMvRixPQUFPLEtBQUssQ0FBQTtTQUNiO1FBRUQsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUU7WUFDM0MsT0FBTyxLQUFLLENBQUE7U0FDYjtRQUVELHVDQUF1QztRQUN2QyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQTtRQUMvRCxJQUFJLFFBQVEsSUFBSSxRQUFRLENBQUMsdUJBQXVCLEtBQUssU0FBUyxFQUFFO1lBQzlELE9BQU8sUUFBUSxDQUFDLHVCQUF1QixDQUFBO1NBQ3hDO1FBRUQsMEVBQTBFO1FBQzFFLElBQUksZUFBZSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFBO1FBQ3pDLE1BQU0sUUFBUSxHQUFHLENBQUMsQ0FBQTtRQUNsQixJQUFJLEtBQUssR0FBRyxDQUFDLENBQUE7UUFFYixPQUFPLGVBQWUsSUFBSSxLQUFLLEdBQUcsUUFBUSxFQUFFO1lBQzFDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxlQUFlLENBQUMsQ0FBQTtZQUN6RCxJQUFJLFVBQVUsRUFBRTtnQkFDZCxJQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsSUFBSSxVQUFVLENBQUMsZUFBZSxLQUFLLFdBQVcsSUFBSSxVQUFVLENBQUMsY0FBYyxLQUFLLFdBQVcsQ0FBQztvQkFDbkgsQ0FBQyxVQUFVLENBQUMsZ0JBQWdCLElBQUksVUFBVSxDQUFDLFFBQVEsQ0FBQyxFQUFFO29CQUN4RCxPQUFPLElBQUksQ0FBQTtpQkFDWjtnQkFDRCxlQUFlLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQTthQUNwQztpQkFBTTtnQkFDTCxNQUFLO2FBQ047WUFDRCxLQUFLLEVBQUUsQ0FBQTtTQUNSO1FBQ0QsT0FBTyxLQUFLLENBQUE7SUFDZCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNLLDRCQUE0QjtRQUNsQyxJQUFJLENBQUMsSUFBSSxDQUFDLG1CQUFtQixJQUFJLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxjQUFjLEtBQUssa0JBQWtCLEVBQUU7WUFDL0YsT0FBTyxLQUFLLENBQUE7U0FDYjtRQUVELElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFO1lBQzNDLE9BQU8sS0FBSyxDQUFBO1NBQ2I7UUFFRCxzQ0FBc0M7UUFDdEMseUZBQXlGO1FBQ3pGLE1BQU0sWUFBWSxHQUNoQixJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsS0FBSyxtQkFBbUI7WUFDcEQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLEtBQUssdUJBQXVCO1lBQ3hELElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxLQUFLLHFDQUFxQztZQUMvRCxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsS0FBSyxrQkFBa0IsQ0FBQTtRQUU5QyxJQUFJLENBQUMsWUFBWSxFQUFFO1lBQ2pCLE9BQU8sS0FBSyxDQUFBO1NBQ2I7UUFFRCxrRUFBa0U7UUFDbEUsbUdBQW1HO1FBQ25HLCtDQUErQztRQUUvQywyRkFBMkY7UUFDM0YsK0RBQStEO1FBQy9ELE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFBO1FBQ3RFLE1BQU0sUUFBUSxHQUFHLGVBQWUsRUFBRSxNQUFNLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUE7UUFFL0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyx3Q0FBd0MsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLElBQUksRUFBRTtZQUN0RyxTQUFTLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVO1lBQ2xDLGVBQWUsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWU7WUFDN0MsUUFBUSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUTtZQUMvQixhQUFhLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNO1lBQ2xDLGFBQWEsRUFBRSxlQUFlLEVBQUUsTUFBTTtZQUN0QyxnQkFBZ0IsRUFBRSxRQUFRO1lBQzFCLGFBQWEsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQztTQUNqRCxDQUFDLENBQUE7UUFFRixJQUFJLFFBQVEsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLEVBQUU7WUFDL0MsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxDQUFBO1lBRWxELE9BQU8sQ0FBQyxHQUFHLENBQUMsb0JBQW9CLEVBQUU7Z0JBQ2hDLFFBQVEsRUFBRSxRQUFRO2dCQUNsQixVQUFVLEVBQUUsVUFBVSxFQUFFLElBQUk7Z0JBQzVCLHFCQUFxQixFQUFFLFVBQVUsRUFBRSxlQUFlO2dCQUNsRCxpQkFBaUIsRUFBRSxVQUFVLEVBQUUsV0FBVztnQkFDMUMsb0JBQW9CLEVBQUUsVUFBVSxFQUFFLGNBQWM7YUFDakQsQ0FBQyxDQUFBO1lBRUYseURBQXlEO1lBQ3pELE1BQU0saUJBQWlCLEdBQUcsVUFBVSxDQUFDLFdBQVc7Z0JBQ3RCLFVBQVUsQ0FBQyxlQUFlLEtBQUssV0FBVztnQkFDMUMsVUFBVSxDQUFDLGNBQWMsS0FBSyxXQUFXLENBQUE7WUFFbkUsSUFBSSxpQkFBaUIsRUFBRTtnQkFDckIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxvRUFBb0UsQ0FBQyxDQUFBO2dCQUNqRixPQUFPLElBQUksQ0FBQTthQUNaO1lBRUQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxzREFBc0QsVUFBVSxDQUFDLGVBQWUsb0JBQW9CLENBQUMsQ0FBQTtZQUNqSCxpRkFBaUY7WUFDakYsaURBQWlEO1lBQ2pELE9BQU8sS0FBSyxDQUFBO1NBQ2I7YUFBTTtZQUNMLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUNBQW1DLFFBQVEsRUFBRSxDQUFDLENBQUE7U0FDM0Q7UUFFRCxPQUFPLEtBQUssQ0FBQTtJQUNkLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSyxrQ0FBa0M7UUFDeEMsaUZBQWlGO1FBQ2pGLGdGQUFnRjtRQUNoRixJQUFJLENBQUMsSUFBSSxDQUFDLG1CQUFtQixJQUFJLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxjQUFjLEtBQUssa0JBQWtCLEVBQUU7WUFDL0YsT0FBTyxLQUFLLENBQUE7U0FDYjtRQUVELG1FQUFtRTtRQUNuRSxNQUFNLHFCQUFxQixHQUFHLElBQUksQ0FBQyw0QkFBNEIsSUFBSSxJQUFJLENBQUMsNEJBQTRCLEVBQUUsQ0FBQTtRQUV0RyxPQUFPLENBQUMsR0FBRyxDQUFDLDhDQUE4QyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksSUFBSSxFQUFFO1lBQ2hGLHFCQUFxQjtZQUNyQiw0QkFBNEIsRUFBRSxJQUFJLENBQUMsNEJBQTRCO1lBQy9ELGNBQWMsRUFBRSxJQUFJLENBQUMsbUJBQW1CLEVBQUUsY0FBYztTQUN6RCxDQUFDLENBQUE7UUFFRixJQUFJLENBQUMscUJBQXFCLEVBQUU7WUFDMUIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSwyQ0FBMkMsQ0FBQyxDQUFBO1lBQ2pGLE9BQU8sS0FBSyxDQUFBO1NBQ2I7UUFFRCw4REFBOEQ7UUFDOUQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixJQUFJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLFVBQVUsSUFBSSxFQUFFLENBQUMsQ0FBQTtRQUMvRixJQUFJLFFBQVEsSUFBSSxRQUFRLENBQUMsa0JBQWtCLEtBQUssU0FBUyxFQUFFO1lBQ3pELE9BQU8sUUFBUSxDQUFDLGtCQUFrQixDQUFBO1NBQ25DO1FBRUQsbUNBQW1DO1FBQ25DLElBQUksSUFBSSxDQUFDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLEtBQUssQ0FBQztZQUNwRCxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsb0JBQW9CLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsSUFBSSxHQUFHLENBQUMsQ0FBQyxFQUFFO1lBQ3BGLE9BQU8sS0FBSyxDQUFBO1NBQ2I7UUFFRCxvR0FBb0c7UUFDcEcsb0VBQW9FO1FBQ3BFLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxVQUFVLElBQUksRUFBRSxDQUFDLENBQUE7UUFDdEcsTUFBTSxXQUFXLEdBQUcsZUFBZSxFQUFFLE1BQU0sSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQTtRQUVuRSxJQUFJLENBQUMsV0FBVyxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFO1lBQzFDLE9BQU8sS0FBSyxDQUFBO1NBQ2I7UUFFRCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxDQUFDLENBQUE7UUFFcEQsSUFBSSxDQUFDLFNBQVMsRUFBRTtZQUNkLE9BQU8sS0FBSyxDQUFBO1NBQ2I7UUFFRCx5RUFBeUU7UUFDekUsbUNBQW1DO1FBQ25DLElBQUksU0FBUyxDQUFDLGdCQUFnQixJQUFJLFNBQVMsQ0FBQyxRQUFRLEVBQUU7WUFDcEQsT0FBTyxLQUFLLENBQUE7U0FDYjtRQUVELGdFQUFnRTtRQUNoRSx3RUFBd0U7UUFDeEUsSUFBSSxjQUFjLEdBQUcsQ0FBQyxDQUFBO1FBQ3RCLElBQUksdUJBQXVCLEdBQUcsQ0FBQyxDQUFBO1FBRS9CLEtBQUssTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsRUFBRTtZQUNwRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUE7WUFFdkMsOERBQThEO1lBQzlELElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxXQUFXO2dCQUFFLFNBQVE7WUFFekMsd0RBQXdEO1lBQ3hELElBQUksSUFBSSxDQUFDLGVBQWUsS0FBSyxRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWTtnQkFBRSxTQUFRO1lBRXJFLGdDQUFnQztZQUNoQyxNQUFNLGdCQUFnQixHQUNwQixJQUFJLENBQUMsZUFBZSxLQUFLLG1CQUFtQjtnQkFDNUMsSUFBSSxDQUFDLGVBQWUsS0FBSyxrQkFBa0I7Z0JBQzNDLElBQUksQ0FBQyxlQUFlLEtBQUssdUJBQXVCO2dCQUNoRCxJQUFJLENBQUMsUUFBUSxLQUFLLHFDQUFxQyxDQUFBO1lBQ3pELElBQUksZ0JBQWdCO2dCQUFFLFNBQVE7WUFFOUIseUVBQXlFO1lBQ3pFLElBQUksSUFBSSxDQUFDLFdBQVcsS0FBSyxLQUFLLEVBQUU7Z0JBQzlCLGNBQWMsRUFBRSxDQUFBO2dCQUNoQixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQztvQkFDakQsSUFBSSxDQUFDLG9CQUFvQixJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsUUFBUSxJQUFJLEdBQUcsQ0FBQTtnQkFDM0UsSUFBSSxXQUFXLEVBQUU7b0JBQ2YsdUJBQXVCLEVBQUUsQ0FBQTtpQkFDMUI7YUFDRjtTQUNGO1FBRUQsNERBQTREO1FBQzVELElBQUksY0FBYyxLQUFLLENBQUMsRUFBRTtZQUN4QixPQUFPLEtBQUssQ0FBQTtTQUNiO1FBRUQsNkRBQTZEO1FBQzdELE1BQU0sb0JBQW9CLEdBQUcsdUJBQXVCLElBQUksY0FBYyxDQUFBO1FBQ3RFLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQTtJQUM5QixDQUFDO0lBRUQsNkNBQTZDO0lBQzdDLGNBQWM7UUFDWixJQUFJLENBQUMsc0JBQXNCLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsQ0FBQyxLQUFjLEVBQUUsRUFBRTtZQUN6RixJQUFJLEtBQUssRUFBRTtnQkFDVCxVQUFVLENBQUMsR0FBRyxFQUFFO29CQUNkLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQTtnQkFDbkIsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFBO2FBQ1I7UUFDSCxDQUFDLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFDRCwwREFBMEQ7SUFDMUQsY0FBYztRQUNaLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUN6QyxDQUFDO0lBRUQsV0FBVyxDQUFDLE9BQXNCO1FBQ2hDLElBQUksb0JBQW9CLEdBQUcsS0FBSyxDQUFBO1FBRWhDLEtBQUssTUFBTSxRQUFRLElBQUksT0FBTyxFQUFFO1lBQzlCLElBQUksUUFBUSxLQUFLLFdBQVcsRUFBRTtnQkFDNUIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFBO2FBQ25DO1lBQ0QsSUFBSSxRQUFRLEtBQUssU0FBUyxJQUFJLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRTtnQkFDaEQsSUFBSSxZQUFZLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLFlBQVksQ0FBQTtnQkFDbEQsSUFBSSxhQUFhLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLGFBQWEsQ0FBQTtnQkFDcEQsSUFBSSxZQUFZLElBQUksYUFBYSxFQUFFO29CQUNqQyxNQUFNLEtBQUssR0FBRyxDQUFDLEVBQU8sRUFBRSxFQUFPLEVBQUUsRUFBRSxDQUNqQyxFQUFFLENBQUMsSUFBSSxLQUFLLEVBQUUsQ0FBQyxJQUFJO3dCQUNuQixDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7b0JBQ2pDLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLFlBQVksQ0FBQyxFQUFFLEdBQUc7aUJBQzdDO2dCQUNELG1DQUFtQztnQkFDbkMscUJBQXFCO2dCQUNyQixXQUFXO2dCQUNYLElBQUk7YUFDTDtZQUNELDBDQUEwQztZQUUxQyxJQUFJLFFBQVEsS0FBSyxrQkFBa0IsRUFBRTtnQkFDbkMsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLFlBQVksQ0FBQyxFQUFFO29CQUN2RCxxQ0FBcUM7aUJBQ3RDO3FCQUFNO29CQUNMLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTt3QkFDaEIsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUE7cUJBQ25EO29CQUNELG9CQUFvQixHQUFHLElBQUksQ0FBQTtpQkFDNUI7YUFDRjtZQUVELDhDQUE4QztZQUM5QyxJQUFJLFFBQVEsS0FBSyxTQUFTLElBQUksUUFBUSxLQUFLLHFCQUFxQjtnQkFDNUQsUUFBUSxLQUFLLFNBQVMsSUFBSSxRQUFRLEtBQUssWUFBWTtnQkFDbkQsUUFBUSxLQUFLLHVCQUF1QixJQUFJLFFBQVEsS0FBSyxVQUFVLEVBQUU7Z0JBQ25FLG9CQUFvQixHQUFHLElBQUksQ0FBQTthQUM1QjtTQUNGO1FBRUQsNENBQTRDO1FBQzVDLElBQUksb0JBQW9CLEVBQUU7WUFDeEIsSUFBSSxDQUFDLDBCQUEwQixFQUFFLENBQUE7U0FDbEM7UUFDRCx5REFBeUQ7UUFDekQsaUVBQWlFO0lBQ25FLENBQUM7SUFFRCxLQUFLLENBQUMsT0FBWTtRQUNoQixJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDckIsT0FBTyxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsSUFBSSxPQUFPLENBQUMsWUFBWSxDQUFBO1NBQ3BHO1FBQ0QsT0FBTyxPQUFPLENBQUMsWUFBWSxDQUFBO0lBQzdCLENBQUM7SUFFRCxJQUFJLFlBQVk7UUFDZCxJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtZQUMxQixPQUFPLElBQUksQ0FBQyxtQkFBbUIsQ0FBQTtTQUNoQztRQUNELElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNoQixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxLQUFLLFNBQVMsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFBO1NBQ2pFO1FBQ0QsT0FBTyxLQUFLLENBQUE7SUFDZCxDQUFDO0lBRUQsSUFBSSxRQUFRO1FBQ1YsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUU7WUFDMUIsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFBO1NBQzVCO1FBQ0QsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ2hCLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQTtTQUMxRTtRQUNELE9BQU8sS0FBSyxDQUFBO0lBQ2QsQ0FBQztJQUVNLFdBQVcsQ0FBQyxPQUFrQztRQUNuRCxJQUFJLE9BQU8sRUFBRTtZQUNYLE9BQU8sT0FBTyxDQUFDLGVBQWUsS0FBSyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFBO1NBQ3JFO1FBQ0QsT0FBTyxLQUFLLENBQUE7SUFDZCxDQUFDO0lBRUQsYUFBYSxDQUFDLE9BQVk7UUFDeEIsSUFBSSxPQUFPLEVBQUU7WUFDWCxPQUFPLE9BQU8sQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQTtTQUNyRTtRQUNELE9BQU8sS0FBSyxDQUFBO0lBQ2QsQ0FBQztJQUVELElBQUksZ0JBQWdCO1FBQ2xCLElBQUksSUFBSSxDQUFDLFNBQVMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFO1lBQzFHLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFBO1lBQzNDLElBQUksU0FBUyxJQUFJLFNBQVMsQ0FBQyxPQUFPLEVBQUU7Z0JBQ2xDLE1BQU0sR0FBRyxHQUFHLE1BQU0sRUFBRSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQTtnQkFDekMsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUE7Z0JBQ2xFLE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUE7Z0JBQ3hGLE9BQU87Z0JBQ0wsa0JBQWtCO2dCQUNsQixNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQzt1QkFDbEMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FDdEMsQ0FBQTthQUNGO1lBQUMsT0FBTyxJQUFJLENBQUE7U0FDZDtRQUNELE9BQU8sS0FBSyxDQUFBO0lBQ2QsQ0FBQztJQUVELElBQUksVUFBVTtRQUNaLElBQUksSUFBSSxDQUFDLGlCQUFpQixFQUFFO1lBQzFCLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixDQUFBO1NBQzlCO1FBQ0QsT0FBTyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQTtJQUNqQyxDQUFDO0lBRUQsSUFBSSxZQUFZO1FBQ2QsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUU7WUFDMUIsT0FBTyxJQUFJLENBQUMsbUJBQW1CLENBQUE7U0FDaEM7UUFDRCxPQUFPLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFBO0lBQ25DLENBQUM7SUFFTSxhQUFhO1FBQ2xCLG9DQUFvQztRQUNwQyxxQkFBcUI7UUFDckIsbUVBQW1FO1FBQ25FLHFCQUFxQjtRQUNyQixJQUFJO1FBQ0osa0VBQWtFO1FBQ2xFLHFCQUFxQjtRQUNyQixJQUFJO1FBRUosT0FBTyxTQUFTLENBQUE7SUFDbEIsQ0FBQztJQUNNLGNBQWM7UUFDbkIsT0FBTyxTQUFTLENBQUE7SUFDbEIsQ0FBQztJQUVPLGtDQUFrQztRQUN4QyxJQUFJLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFO1lBQ3pFLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQXlCLEVBQUUsRUFBRTtnQkFDMUQsSUFBSSxLQUFLLENBQUMsZUFBZSxLQUFLLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUU7b0JBQy9ELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFBO2lCQUNsQztxQkFBTSxJQUFJLEtBQUssQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLGtCQUFrQixFQUFFO29CQUNsRixJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQTtpQkFDakM7cUJBQU0sSUFBSSxLQUFLLENBQUMsZUFBZSxLQUFLLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUU7b0JBQ3RFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxjQUFjLElBQUksQ0FBQyxDQUFBO2lCQUMxQztxQkFBTSxJQUFJLEtBQUssQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLGVBQWUsRUFBRTtvQkFDL0UsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGNBQWMsSUFBSSxDQUFDLENBQUE7aUJBQzFDO3FCQUFNLElBQUksS0FBSyxDQUFDLGVBQWUsS0FBSyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxFQUFFO29CQUN4RSxRQUFRLEtBQUssQ0FBQyxRQUFRLEVBQUU7d0JBQ3RCLEtBQUssU0FBUyxDQUFDLFVBQVUsQ0FBQyxRQUFROzRCQUNoQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxJQUFJLENBQUMsQ0FBQTs0QkFDbEMsTUFBSzt3QkFDUCxLQUFLLFNBQVMsQ0FBQyxVQUFVLENBQUMsR0FBRzs0QkFDM0IsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sSUFBSSxDQUFDLENBQUE7NEJBQ2xDLE1BQUs7d0JBQ1AsS0FBSyxTQUFTLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQzt3QkFDOUIsS0FBSyxTQUFTLENBQUMsVUFBVSxDQUFDLElBQUk7NEJBQzVCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFBOzRCQUNoQyxNQUFLO3dCQUNQLEtBQUssU0FBUyxDQUFDLFVBQVUsQ0FBQyxXQUFXOzRCQUNuQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsZ0JBQWdCLElBQUksQ0FBQyxDQUFBOzRCQUMzQyxNQUFLO3dCQUNQLEtBQUssU0FBUyxDQUFDLFVBQVUsQ0FBQyxHQUFHOzRCQUMzQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQTs0QkFDOUIsTUFBSzt3QkFDUCxLQUFLLFNBQVMsQ0FBQyxVQUFVLENBQUMsZUFBZTs0QkFDdkMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGNBQWMsSUFBSSxDQUFDLENBQUE7NEJBQ3pDLE1BQUs7d0JBQ1AsS0FBSyxTQUFTLENBQUMsVUFBVSxDQUFDLE1BQU07NEJBQzlCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFBOzRCQUNqQyxNQUFLO3dCQUNQLEtBQUssU0FBUyxDQUFDLFVBQVUsQ0FBQyxJQUFJOzRCQUM1QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxJQUFJLENBQUMsQ0FBQTs0QkFDbEMsTUFBSzt3QkFDUCxLQUFLLFNBQVMsQ0FBQyxVQUFVLENBQUMsSUFBSTs0QkFDNUIsSUFBSSxLQUFLLENBQUMsWUFBWSxLQUFLLFlBQVksRUFBRTtnQ0FDdkMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsSUFBSSxDQUFDLENBQUE7NkJBQ3RDO2lDQUFNO2dDQUNMLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFBOzZCQUNoQzs0QkFDRCxNQUFLO3dCQUNQLEtBQUssU0FBUyxDQUFDLFVBQVUsQ0FBQyxpQkFBaUI7NEJBQ3pDLDhDQUE4Qzs0QkFDOUMsK0NBQStDOzRCQUMvQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxJQUFJLENBQUMsQ0FBQTs0QkFDdkMsTUFBSzt3QkFDUCxLQUFLLFNBQVMsQ0FBQyxVQUFVLENBQUMsVUFBVTs0QkFDbEMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsSUFBSSxDQUFDLENBQUE7NEJBQ3BDLE1BQUs7d0JBQ1AsS0FBSyxTQUFTLENBQUMsVUFBVSxDQUFDLE9BQU87NEJBQy9CLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFBOzRCQUNsQyxNQUFLO3dCQUNQOzRCQUNFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFBOzRCQUNoQyxNQUFLO3FCQUNSO2lCQUNGO1lBQ0gsQ0FBQyxDQUFDLENBQUE7U0FDSDtRQUNELEtBQUssTUFBTSxHQUFHLElBQUksSUFBSSxDQUFDLGdCQUFnQixFQUFFO1lBQ3ZDLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRTtnQkFDbEMsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQTthQUNoQztTQUNGO0lBQ0gsQ0FBQztJQUVELElBQUksV0FBVztRQUNiLE9BQU87WUFDTCxTQUFTLEVBQUUsSUFBSSxDQUFDLE1BQU07WUFDdEIsV0FBVyxFQUFFLElBQUksQ0FBQyxlQUFlO1lBQ2pDLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztTQUN0QixDQUFBO0lBQ0gsQ0FBQztJQUVNLGNBQWMsQ0FBQyxNQUFjLEVBQUUsT0FBMkI7UUFDL0QsSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNaLE9BQU8sSUFBSSxDQUFBO1NBQ1o7UUFDRCxPQUFPLE9BQU8sQ0FBQyxVQUFVLENBQUE7SUFDM0IsQ0FBQztJQUVNLGNBQWM7UUFDbkIsa0NBQWtDO1FBQ2xDLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNoQixJQUFJLENBQUMsTUFBTSxDQUFDLHNCQUFzQixDQUNoQztnQkFDRSxJQUFJLEVBQUUsT0FBTztnQkFDYixPQUFPLEVBQUUscUJBQXFCO2dCQUM5QixxQ0FBcUM7YUFDdEMsRUFDRDtnQkFDRSw0Q0FBNEM7Z0JBQzVDLDZDQUE2QztnQkFDN0MsRUFBRSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxJQUFJLEVBQUU7Z0JBQ2pDLElBQUksRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWU7Z0JBQ2xDLE1BQU0sRUFBRTtvQkFDTixFQUFFLEVBQUUsSUFBSSxDQUFDLE1BQU0sSUFBSSxFQUFFO2lCQUN0QjtnQkFDRCxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sR0FBRyxFQUFFLEVBQUU7YUFDcEMsRUFDRDtnQkFDRSxTQUFTLEVBQUUsR0FBRyxDQUFDLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUFDLE9BQU87Z0JBQzlELE1BQU0sRUFBRSxDQUFDLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUFDO2FBQ2xELENBQUMsQ0FBQTtTQUNMO0lBQ0gsQ0FBQztJQUNELElBQUksU0FBUztRQUNYLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNoQixPQUFPLENBQUMsQ0FBQyxTQUFTLENBQUMsMkNBQTJDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUE7U0FDcEc7UUFBQyxPQUFPLEtBQUssQ0FBQTtJQUNoQixDQUFDO0lBRUQsSUFBSSxTQUFTO1FBQ1gsT0FBTyxJQUFJLENBQUE7SUFDYixDQUFDO0lBRUQsSUFBSSxVQUFVO1FBQ1oseUVBQXlFO1FBQ3pFLDZGQUE2RjtRQUM3RixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFFBQVEsSUFBSSxLQUFLLENBQUMsQ0FBQTtJQUNsRSxDQUFDO0lBRUQsb0JBQW9CLENBQUMsVUFBa0I7UUFDckMsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxFQUFFO1lBQzlELElBQUksZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFBO1lBQ3hELElBQ0UsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLGVBQWUsS0FBSyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsUUFBUTttQkFDckUsZ0JBQWdCLENBQUMsZUFBZSxLQUFLLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxpQkFBaUI7bUJBQ2pGLGdCQUFnQixDQUFDLGVBQWUsS0FBSyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsZ0JBQWdCO21CQUNoRixnQkFBZ0IsQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLGVBQWUsQ0FBQyxFQUNyRjtnQkFDQSxxQkFBcUI7Z0JBQ3JCLHNGQUFzRjtnQkFDdEYsa0ZBQWtGO2dCQUNsRiw2Q0FBNkM7Z0JBQzdDLCtCQUErQjtnQkFDL0Isa0JBQWtCO2dCQUNsQixnSkFBZ0o7Z0JBQ2hKLElBQUk7Z0JBQ0osSUFBSSxnQkFBZ0IsQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLE1BQU0sRUFBRTtvQkFDMUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUNoRyxDQUFDLEdBQVEsRUFBRSxPQUFZLEVBQUUsRUFBRTt3QkFDekIsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxFQUFFOzRCQUMzRCxPQUFPLEdBQUcsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLENBQUMsZ0JBQWdCLElBQUksQ0FBQyxDQUFDLENBQUE7eUJBQ3JIO29CQUVILENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQTtpQkFDUjtnQkFDRCxpQkFBaUI7Z0JBQ2pCLE1BQU0sY0FBYyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUMsb0JBQW9CLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFBO2dCQUMzTixNQUFNLFVBQVUsR0FBRyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxFQUFFLGdCQUFnQixDQUFDLENBQUMsSUFBSSxDQUFDLENBQUE7Z0JBQy9GLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxzQkFBc0IsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFDLE1BQU0sR0FBRyxVQUFVLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFBO2dCQUMxSCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxvQkFBb0IsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7YUFDaEk7WUFDRCxPQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQTtTQUN6QztRQUNELE9BQU8sRUFBRSxDQUFBO0lBQ1gsQ0FBQztJQUVELHVCQUF1QixDQUFDLFVBQWtCO1FBQ3hDLHFEQUFxRDtRQUNyRCx5RkFBeUY7UUFDekYscURBQXFEO1FBQ3JELElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDLG9CQUFvQixJQUFJLENBQUMsQ0FBQTtRQUN2SSxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUE7SUFDckMsQ0FBQztJQUVELGNBQWMsQ0FBQyxLQUFhO1FBQzFCLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFO1lBQzVCLE9BQU8sVUFBVSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtTQUNwQztRQUNELE9BQU8sS0FBSyxDQUFBO0lBQ2QsQ0FBQztJQUdELG1CQUFtQixDQUFDLFVBQWtCO1FBQ3BDLHFDQUFxQztRQUNyQyxxREFBcUQ7UUFDckQsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQTtJQUN6SCxDQUFDO0lBRUQscUJBQXFCLENBQUMsUUFBYTtRQUNqQyxNQUFNLEdBQUcsR0FBRyxRQUFRLENBQUE7UUFDcEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsMEJBQTBCLEVBQUU7WUFDM0MsbUJBQW1CO1lBQ25CLEtBQUssRUFBRSxRQUFRO1lBQ2YsSUFBSSxFQUFFLEVBQUUsR0FBRyxFQUFFO1lBQ2IseUNBQXlDO1NBQzFDLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFDRCxVQUFVO1FBQ1IsSUFBSTtZQUNGLElBQUksVUFBVSxHQUFRLElBQUksQ0FBQyxRQUFRLENBQUMsaUJBQWlCLENBQUMsc0NBQXNDLENBQUMsQ0FBQTtZQUM3RixJQUFJLFVBQVUsRUFBRTtnQkFDZCxVQUFVLENBQUMsY0FBYyxDQUFDLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFBO2FBQ3JGO1lBQ0QsSUFBSSxJQUFJLENBQUMsYUFBYSxLQUFLLEtBQUssRUFBRTtnQkFDaEMsSUFBSSxVQUFVLEVBQUU7b0JBQ2QsTUFBTSxJQUFJLEdBQUcsVUFBVSxDQUFDLHFCQUFxQixFQUFFLENBQUE7b0JBQy9DLElBQUksSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxFQUFFO3dCQUN0QixNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFBO3FCQUNuQztpQkFDRjthQUNGO1lBQ0QsVUFBVSxDQUFDLEdBQUcsRUFBRTtnQkFDZCxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7WUFDMUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFBO1lBRVAsU0FBUztZQUNULDBGQUEwRjtZQUMxRixxREFBcUQ7WUFDckQscUNBQXFDO1lBQ3JDLElBQUk7U0FDTDtRQUFDLE9BQU8sR0FBRyxFQUFFO1NBQ2I7SUFDSCxDQUFDO0lBRUQsbUJBQW1CLENBQUMsZUFBb0I7UUFDdEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsQ0FDaEM7WUFDRSxJQUFJLEVBQUUsUUFBUSxDQUFDLGlCQUFpQixDQUFDLEtBQUs7WUFDdEMsRUFBRSxFQUFFLGtCQUFrQjtZQUN0QixPQUFPLEVBQUUsUUFBUSxDQUFDLG9CQUFvQixDQUFDLFdBQVc7U0FDbkQsRUFDRDtZQUNFLEVBQUUsRUFBRSxlQUFlO1lBQ25CLElBQUksRUFBRSxRQUFRLENBQUMsb0JBQW9CLENBQUMsV0FBVztTQUNoRCxDQUFDLENBQUE7UUFDSixJQUFJLGVBQWUsRUFBRTtZQUNuQixJQUFJLENBQUMsMEJBQTBCLEdBQUcsSUFBSSxDQUFBO1lBQ3RDLElBQUksUUFBUSxHQUFRLGVBQWUsQ0FBQTtZQUNuQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsc0JBQXNCLENBQUMsUUFBUSxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsR0FBUSxFQUFFLEVBQUU7Z0JBQzlFLElBQUksQ0FBQywwQkFBMEIsR0FBRyxLQUFLLENBQUE7Z0JBQ3ZDLE1BQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFBO2dCQUMvQixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQywwQkFBMEIsRUFBRTtvQkFDM0MsS0FBSyxFQUFFLFFBQVE7b0JBQ2YsSUFBSSxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxRQUFRLENBQUMsVUFBVSxFQUFFO2lCQUMzQyxDQUFDLENBQUE7WUFDSixDQUFDLENBQUMsQ0FBQTtTQUNIO2FBQU07WUFDTCxJQUFJLENBQUMsMEJBQTBCLEdBQUcsS0FBSyxDQUFBO1NBQ3hDO0lBQ0gsQ0FBQztJQUNELFdBQVc7UUFDVCxJQUFJLElBQUksQ0FBQywwQkFBMEIsRUFBRTtZQUNuQyxJQUFJLENBQUMsMEJBQTBCLENBQUMsV0FBVyxFQUFFLENBQUE7U0FDOUM7UUFDRCxJQUFJLElBQUksQ0FBQyxzQkFBc0IsRUFBRTtZQUMvQixJQUFJLENBQUMsc0JBQXNCLENBQUMsV0FBVyxFQUFFLENBQUE7U0FDMUM7SUFDSCxDQUFDO0lBRUQsSUFBSSxzQkFBc0I7UUFDeEIsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUU7WUFDMUIsT0FBTyxJQUFJLENBQUMsNkJBQTZCLENBQUE7U0FDMUM7UUFDRCxPQUFPLElBQUksQ0FBQyw2QkFBNkIsRUFBRSxDQUFBO0lBQzdDLENBQUM7SUFFRCxJQUFJLGlCQUFpQjtRQUNuQixJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtZQUMxQixPQUFPLElBQUksQ0FBQyx3QkFBd0IsQ0FBQTtTQUNyQztRQUNELE9BQU8sSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUE7SUFDeEMsQ0FBQztJQUVELElBQUksdUJBQXVCO1FBQ3pCLElBQUksSUFBSSxDQUFDLGlCQUFpQixFQUFFO1lBQzFCLE9BQU8sSUFBSSxDQUFDLDhCQUE4QixDQUFBO1NBQzNDO1FBQ0QsT0FBTyxJQUFJLENBQUMsOEJBQThCLEVBQUUsQ0FBQTtJQUM5QyxDQUFDO0lBRUQsSUFBSSxpQkFBaUI7UUFDbkIsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUU7WUFDMUIsT0FBTyxJQUFJLENBQUMsd0JBQXdCLENBQUE7U0FDckM7UUFDRCxPQUFPLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFBO0lBQ3hDLENBQUM7SUFFRCxJQUFJLHFCQUFxQjtRQUN2QixJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtZQUMxQixPQUFPLElBQUksQ0FBQyw0QkFBNEIsQ0FBQTtTQUN6QztRQUNELE9BQU8sSUFBSSxDQUFDLDRCQUE0QixFQUFFLENBQUE7SUFDNUMsQ0FBQztJQUVELElBQUksMkJBQTJCO1FBQzdCLElBQUksSUFBSSxDQUFDLGlCQUFpQixFQUFFO1lBQzFCLE9BQU8sSUFBSSxDQUFDLGtDQUFrQyxDQUFBO1NBQy9DO1FBQ0QsT0FBTyxJQUFJLENBQUMsa0NBQWtDLEVBQUUsQ0FBQTtJQUNsRCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssK0JBQStCLENBQUMsV0FBbUI7UUFDekQsSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUU7WUFDN0YsNEVBQTRFO1lBQzVFLE9BQU8sSUFBSSxDQUFDLGtDQUFrQyxDQUFDLFdBQVcsQ0FBQyxDQUFBO1NBQzVEO1FBRUQsOENBQThDO1FBQzlDLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxXQUFXLENBQUMsQ0FBQTtRQUMzRixJQUFJLENBQUMsZ0JBQWdCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUU7WUFDbkQsT0FBTyxJQUFJLENBQUMsa0NBQWtDLENBQUMsV0FBVyxDQUFDLENBQUE7U0FDNUQ7UUFFRCw4Q0FBOEM7UUFDOUMsSUFBSSxvQkFBb0IsR0FBRyxJQUFJLENBQUE7UUFDL0IsSUFBSSxhQUFhLEdBQUcsS0FBSyxDQUFBO1FBQ3pCLElBQUksa0JBQWtCLEdBQUcsS0FBSyxDQUFBO1FBRTlCLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFVLEVBQUUsRUFBRTtZQUMvQyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFBO1lBQ3pELE1BQU0sWUFBWSxHQUFHLEtBQUssQ0FBQyxlQUFlLEtBQUssbUJBQW1CO2dCQUNoRSxLQUFLLENBQUMsY0FBYyxLQUFLLG1CQUFtQjtnQkFDNUMsS0FBSyxDQUFDLGVBQWUsS0FBSyxrQkFBa0IsQ0FBQTtZQUM5QyxNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsU0FBUyxLQUFLLElBQUksSUFBSSxLQUFLLENBQUMsZUFBZSxLQUFLLElBQUksQ0FBQTtZQUU5RSxJQUFJLFlBQVksRUFBRTtnQkFDaEIsYUFBYSxHQUFHLElBQUksQ0FBQTtnQkFDcEIsSUFBSSxTQUFTLElBQUksQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLEtBQUssQ0FBQyxJQUFJLFNBQVMsQ0FBQyxvQkFBb0IsSUFBSSxHQUFHLENBQUMsRUFBRTtvQkFDNUYsa0JBQWtCLEdBQUcsSUFBSSxDQUFBO2lCQUMxQjthQUNGO2lCQUFNLElBQUksV0FBVyxFQUFFO2dCQUN0QiwwQ0FBMEM7Z0JBQzFDLElBQUksQ0FBQyxTQUFTLElBQUksQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLEtBQUssQ0FBQyxJQUFJLFNBQVMsQ0FBQyxvQkFBb0IsR0FBRyxHQUFHLENBQUMsRUFBRTtvQkFDNUYsb0JBQW9CLEdBQUcsS0FBSyxDQUFBO2lCQUM3QjthQUNGO1FBQ0gsQ0FBQyxDQUFDLENBQUE7UUFFRixPQUFPLENBQUMsR0FBRyxDQUFDLDBCQUEwQixFQUFFLEVBQUUsb0JBQW9CLEVBQUUsYUFBYSxFQUFFLGtCQUFrQixFQUFFLENBQUMsQ0FBQTtRQUVwRyxxR0FBcUc7UUFDckcsT0FBTyxhQUFhLENBQUMsQ0FBQyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQTtJQUNsRSxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSyxrQ0FBa0MsQ0FBQyxXQUFtQjtRQUM1RCxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFO1lBQzFCLE9BQU8sS0FBSyxDQUFBO1NBQ2I7UUFFRCw0REFBNEQ7UUFDNUQsTUFBTSxZQUFZLEdBQUcsUUFBUSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQ2xFLE1BQU0sNEJBQTRCLEdBQUcsWUFBWSxHQUFHLENBQUMsQ0FBQSxDQUFDLGlDQUFpQztRQUV2RixPQUFPLENBQUMsR0FBRyxDQUFDLGFBQWEsV0FBVyxVQUFVLFlBQVksY0FBYyw0QkFBNEIsd0JBQXdCLENBQUMsQ0FBQTtRQUU3SCxJQUFJLDRCQUE0QixJQUFJLENBQUMsRUFBRTtZQUNyQyxPQUFPLElBQUksQ0FBQSxDQUFDLG1DQUFtQztTQUNoRDtRQUVELGdGQUFnRjtRQUNoRixpR0FBaUc7UUFDakcsSUFBSSxpQ0FBaUMsR0FBRyxDQUFDLENBQUE7UUFDekMsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsVUFBVSxDQUFBO1FBRTlELEtBQUssTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsRUFBRTtZQUNwRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUE7WUFFdkMsOENBQThDO1lBQzlDLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxLQUFLLG1CQUFtQixJQUFJLElBQUksQ0FBQyxjQUFjLEtBQUssbUJBQW1CLENBQUM7Z0JBQy9GLENBQUMsSUFBSSxDQUFDLGdCQUFnQixLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsb0JBQW9CLElBQUksR0FBRyxDQUFDLEVBQUU7Z0JBRW5FLG9HQUFvRztnQkFDcEcsb0ZBQW9GO2dCQUNwRixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssaUJBQWlCLENBQUE7Z0JBRWxFLElBQUksU0FBUyxFQUFFO29CQUNiLGlDQUFpQyxFQUFFLENBQUE7b0JBQ25DLE9BQU8sQ0FBQyxHQUFHLENBQUMseUNBQXlDLEdBQUcsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFBO2lCQUNsRTtxQkFBTTtvQkFDTCxPQUFPLENBQUMsR0FBRyxDQUFDLGtEQUFrRCxHQUFHLEVBQUUsQ0FBQyxDQUFBO2lCQUNyRTthQUNGO1NBQ0Y7UUFFRCxPQUFPLENBQUMsR0FBRyxDQUFDLDBDQUEwQyxpQ0FBaUMsZUFBZSw0QkFBNEIsRUFBRSxDQUFDLENBQUE7UUFFckksMkVBQTJFO1FBQzNFLE9BQU8saUNBQWlDLElBQUksNEJBQTRCLENBQUE7SUFDMUUsQ0FBQztJQUVPLHNCQUFzQixDQUFDLE9BQVksRUFBRSxVQUFrQjtRQUM3RCxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU8sSUFBSSxDQUFBO1FBQ3pCLElBQUksT0FBTyxDQUFDLFVBQVUsS0FBSyxVQUFVO1lBQUUsT0FBTyxPQUFPLENBQUE7UUFDckQsSUFBSSxPQUFPLENBQUMsUUFBUSxFQUFFO1lBQ3BCLEtBQUssTUFBTSxLQUFLLElBQUksT0FBTyxDQUFDLFFBQVEsRUFBRTtnQkFDcEMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUFDLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQTtnQkFDNUQsSUFBSSxLQUFLO29CQUFFLE9BQU8sS0FBSyxDQUFBO2FBQ3hCO1NBQ0Y7UUFDRCxPQUFPLElBQUksQ0FBQTtJQUNiLENBQUM7SUFFRCxJQUFJLG1CQUFtQjtRQUNyQixJQUFJLElBQUksQ0FBQyxTQUFTLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDeEQsT0FBTztnQkFDTCxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVztnQkFDaEMsYUFBYSxFQUFFLE1BQU07YUFDdEIsQ0FBQTtTQUNGO1FBQ0QsT0FBTyxJQUFJLENBQUE7SUFDYixDQUFDO0lBRUQsSUFBSSxXQUFXO1FBQ2IsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUU7WUFDMUIsT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQUE7U0FDL0I7UUFDRCxPQUFPLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFBO0lBQ2xDLENBQUM7SUFFRCwwQkFBMEI7UUFDeEIsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUU7WUFDM0MsT0FBTyxDQUFDLENBQUE7U0FDVDtRQUNELE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFBO1FBQ3BFLElBQUksQ0FBQyxhQUFhLElBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxFQUFFO1lBQzlDLE9BQU8sQ0FBQyxDQUFBO1NBQ1Q7UUFDRCxJQUFJLGNBQWMsR0FBRyxDQUFDLENBQUE7UUFDdEIsYUFBYSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFjLEVBQUUsRUFBRTtZQUNqRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUE7WUFDOUMsSUFBSSxRQUFRLElBQUksUUFBUSxDQUFDLGdCQUFnQixLQUFLLENBQUMsRUFBRTtnQkFDL0MsY0FBYyxFQUFFLENBQUE7YUFDakI7UUFDSCxDQUFDLENBQUMsQ0FBQTtRQUNGLE9BQU8sY0FBYyxDQUFBO0lBQ3ZCLENBQUM7SUFFRDs7T0FFRztJQUNILHlCQUF5QjtRQUN2QixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtZQUMzQyxPQUFPLEVBQUUsQ0FBQTtTQUNWO1FBRUQsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUE7UUFDcEUsSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUNsQixPQUFPLEVBQUUsQ0FBQTtTQUNWO1FBRUQsbURBQW1EO1FBQ25ELElBQUksYUFBYSxDQUFDLGFBQWEsRUFBRTtZQUMvQixPQUFPLGFBQWEsQ0FBQyxhQUFhLENBQUE7U0FDbkM7UUFFRCxNQUFNLGNBQWMsR0FBRyxhQUFhLENBQUMsY0FBYyxDQUFBO1FBRW5ELGlEQUFpRDtRQUNqRCxJQUFJLGNBQWMsS0FBSyxDQUFDLEVBQUU7WUFDeEIsT0FBTyw4REFBOEQsQ0FBQTtTQUN0RTtRQUVELHlEQUF5RDtRQUN6RCxPQUFPLDhEQUE4RCxjQUFjLDJCQUEyQixDQUFBO0lBQ2hILENBQUM7SUFFRDs7T0FFRztJQUNILDZCQUE2QjtRQUMzQixJQUFJLENBQUMsSUFBSSxDQUFDLHVCQUF1QixFQUFFO1lBQ2pDLE9BQU8sRUFBRSxDQUFBO1NBQ1Y7UUFDRCxPQUFPLDJFQUEyRSxDQUFBO0lBQ3BGLENBQUM7SUFFRDs7T0FFRztJQUNILHdCQUF3QjtRQUN0QixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtZQUMzQyxPQUFPLEVBQUUsQ0FBQTtTQUNWO1FBRUQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUE7UUFFL0QsNERBQTREO1FBQzVELElBQUksUUFBUSxJQUFJLFFBQVEsQ0FBQyxxQkFBcUIsRUFBRTtZQUM5QyxPQUFPLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQTtTQUN0QztRQUVELElBQUksSUFBSSxDQUFDLDJCQUEyQixFQUFFO1lBQ3BDLE9BQU8sZ0ZBQWdGLENBQUE7U0FDeEY7UUFFRCxPQUFPLEVBQUUsQ0FBQTtJQUNYLENBQUM7SUFFRCx3QkFBd0IsQ0FBQyxPQUFrQztRQUN6RCxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ1osT0FBTyxLQUFLLENBQUE7U0FDYjtRQUVELCtEQUErRDtRQUMvRCxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRTtZQUN4QixPQUFPLEtBQUssQ0FBQTtTQUNiO1FBRUQsZ0VBQWdFO1FBQ2hFLElBQUksQ0FBQyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsY0FBYztZQUMzQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsY0FBYyxLQUFLLFNBQVMsQ0FBQyxlQUFlLENBQUMsVUFBVSxFQUFFO1lBQ2xGLE9BQU8sS0FBSyxDQUFBO1NBQ2I7UUFFRCx5RUFBeUU7UUFDekUsSUFBSSxJQUFJLENBQUMsVUFBVSxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxFQUFFO1lBQ2pFLE9BQU8sS0FBSyxDQUFBO1NBQ2I7UUFFRCxxRUFBcUU7UUFDckUsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQ3hDLE9BQU8sS0FBSyxDQUFBO1NBQ2I7UUFFRCxpQ0FBaUM7UUFDakMsTUFBTSxxQkFBcUIsR0FBRztZQUM1QixTQUFTLENBQUMsVUFBVSxDQUFDLEdBQUc7U0FDekIsQ0FBQTtRQUVELE9BQU8scUJBQXFCLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQTtJQUN6RCxDQUFDO0lBRUQsZUFBZSxDQUFDLE9BQTJCLEVBQUUsS0FBa0I7UUFDN0QsSUFBSSxLQUFLLEVBQUU7WUFDVCxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUE7WUFDdEIsS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFBO1NBQ3hCO1FBQ0QsTUFBTSxNQUFNLEdBQUcsa0JBQWtCLE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FBQTtRQUNyRCxJQUFJLENBQUMseUJBQXlCLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQTtRQUMzRCxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsQ0FBQTtRQUMvQixPQUFPLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsQ0FBQTtJQUN0RCxDQUFDO0lBSUQ7O09BRUc7SUFDSCx3QkFBd0IsQ0FBQyxLQUFrQjtRQUN6QyxJQUFJLEtBQUssRUFBRTtZQUNULEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQTtZQUN0QixLQUFLLENBQUMsZUFBZSxFQUFFLENBQUE7U0FDeEI7UUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFO1lBQzdELE9BQU07U0FDUDtRQUVELHlDQUF5QztRQUN6QyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLFdBQVcsRUFBRSxNQUFNLENBQUE7UUFDbEQsSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQTtZQUNsQyxPQUFNO1NBQ1A7UUFFRCx5RUFBeUU7UUFDekUscUVBQXFFO1FBQ3JFLElBQUksV0FBVyxHQUFHLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUEsQ0FBQyxxREFBcUQ7UUFFOUYsd0RBQXdEO1FBQ3hELElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUU7WUFDckIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQixDQUFDLENBQUE7WUFDM0QsSUFBSSxLQUFLLEVBQUU7Z0JBQ1QsV0FBVyxHQUFHLEdBQUcsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUE7YUFDN0I7U0FDRjtRQUVELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxVQUFVLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQTtRQUVwRSxJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFBO1FBRTlCLElBQUksQ0FBQyxTQUFTLENBQUMsNEJBQTRCLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLFdBQVcsQ0FBQyxDQUFDLFNBQVMsQ0FBQztZQUNqRyxJQUFJLEVBQUUsQ0FBQyxRQUFhLEVBQUUsRUFBRTtnQkFDdEIsSUFBSSxDQUFDLGtCQUFrQixHQUFHLEtBQUssQ0FBQTtnQkFDL0IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxxQ0FBcUMsRUFBRSxRQUFRLENBQUMsQ0FBQTtnQkFDNUQsNkNBQTZDO2dCQUM3QyxJQUFJLFFBQVEsSUFBSSxRQUFRLENBQUMsTUFBTSxFQUFFO29CQUMvQix3Q0FBd0M7b0JBQ3hDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLDBCQUEwQixFQUFFO3dCQUMzQyxLQUFLLEVBQUUsUUFBUTt3QkFDZixJQUFJLEVBQUU7NEJBQ0osR0FBRyxFQUFFLFFBQVEsQ0FBQyxNQUFNLENBQUMsUUFBUSxJQUFJLFFBQVEsQ0FBQyxNQUFNLENBQUMsT0FBTzs0QkFDeEQsTUFBTSxFQUFFLFFBQVEsQ0FBQyxNQUFNLENBQUMsVUFBVTs0QkFDbEMsYUFBYSxFQUFFLElBQUk7eUJBQ3BCO3FCQUNGLENBQUMsQ0FBQTtpQkFDSDtZQUNILENBQUM7WUFDRCxLQUFLLEVBQUUsQ0FBQyxLQUFVLEVBQUUsRUFBRTtnQkFDcEIsSUFBSSxDQUFDLGtCQUFrQixHQUFHLEtBQUssQ0FBQTtnQkFDL0IsaUNBQWlDO2dCQUNqQyxNQUFNLFlBQVksR0FBRyxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxPQUFPLElBQUksS0FBSyxFQUFFLE9BQU8sSUFBSSxnQ0FBZ0MsQ0FBQTtnQkFDeEcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLE9BQU8sRUFBRTtvQkFDeEMsUUFBUSxFQUFFLElBQUk7b0JBQ2Qsa0JBQWtCLEVBQUUsUUFBUTtvQkFDNUIsZ0JBQWdCLEVBQUUsUUFBUTtvQkFDMUIsVUFBVSxFQUFFLENBQUMsZ0JBQWdCLENBQUM7aUJBQy9CLENBQUMsQ0FBQTtnQkFDRixPQUFPLENBQUMsS0FBSyxDQUFDLCtCQUErQixFQUFFLEtBQUssQ0FBQyxDQUFBO1lBQ3ZELENBQUM7U0FDRixDQUFDLENBQUE7SUFDSixDQUFDO0lBQ0Y7Ozs7UUFJSTtJQUNILGVBQWUsQ0FBQyxPQUFvQjtRQUNsQyxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU8sS0FBSyxDQUFBO1FBQzFCLE9BQU8sT0FBTyxDQUFDLFdBQVcsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFBO0lBQ2xELENBQUM7SUFFRDs7O09BR0c7SUFDSCxvQkFBb0IsQ0FBQyxPQUFvQjtRQUN2QyxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU8sS0FBSyxDQUFBO1FBQzFCLE9BQU8sT0FBTyxDQUFDLFlBQVksR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFBO0lBQ3BELENBQUM7K0dBbnZDVSw0QkFBNEI7bUdBQTVCLDRCQUE0QixnakJDbEN6Qyx1bG1FQTZ6QmUseTZXRDN4QkYsNEJBQTRCLHlrQkFaM0I7WUFDVixPQUFPLENBQUMsWUFBWSxFQUFFO2dCQUNwQixVQUFVLENBQUMsV0FBVyxFQUFFO29CQUN0QixLQUFLLENBQUMsRUFBRSxTQUFTLEVBQUUsa0JBQWtCLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDO29CQUN0RCxPQUFPLENBQUMsR0FBRyxDQUFDO2lCQUNiLENBQUM7Z0JBQ0YsVUFBVSxDQUFDLFdBQVcsRUFBRTtvQkFDdEIsT0FBTyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsRUFBRSxTQUFTLEVBQUUsa0JBQWtCLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7aUJBQ3JFLENBQUM7YUFDSCxDQUFDO1NBQ0g7OzRGQUVVLDRCQUE0QjtrQkFoQnhDLFNBQVM7K0JBQ0UsbUNBQW1DLGNBR2pDO3dCQUNWLE9BQU8sQ0FBQyxZQUFZLEVBQUU7NEJBQ3BCLFVBQVUsQ0FBQyxXQUFXLEVBQUU7Z0NBQ3RCLEtBQUssQ0FBQyxFQUFFLFNBQVMsRUFBRSxrQkFBa0IsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUM7Z0NBQ3RELE9BQU8sQ0FBQyxHQUFHLENBQUM7NkJBQ2IsQ0FBQzs0QkFDRixVQUFVLENBQUMsV0FBVyxFQUFFO2dDQUN0QixPQUFPLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLFNBQVMsRUFBRSxrQkFBa0IsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQzs2QkFDckUsQ0FBQzt5QkFDSCxDQUFDO3FCQUNIOzJXQUdRLE9BQU87c0JBQWYsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLGdCQUFnQjtzQkFBeEIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBQ0csbUJBQW1CO3NCQUEzQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0cscUJBQXFCO3NCQUE3QixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT25Jbml0LCBPbkRlc3Ryb3ksIFJlbmRlcmVyMiwgU2ltcGxlQ2hhbmdlcyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnXG5pbXBvcnQgeyBOc0NvbnRlbnQgfSBmcm9tICcuLi8uLi8uLi8uLi9fc2VydmljZXMvd2lkZ2V0LWNvbnRlbnQubW9kZWwnXG5pbXBvcnQgeyB2aWV3ZXJSb3V0ZUdlbmVyYXRvciB9IGZyb20gJy4uLy4uLy4uLy4uL19zZXJ2aWNlcy92aWV3ZXItcm91dGUtdXRpbCdcbmltcG9ydCB7IE5zQXBwVG9jIH0gZnJvbSAnLi4vLi4vLi4vLi4vbW9kZWxzL2FwcC10b2MubW9kZWwnXG5pbXBvcnQgeyBFdmVudFNlcnZpY2UsIFdzRXZlbnRzLCBDb25maWd1cmF0aW9uc1NlcnZpY2UgfSBmcm9tICdAc3VuYmlyZC1jYi91dGlscy12MidcbmltcG9ydCB7IENlcnRpZmljYXRlRGlhbG9nQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vY2VydGlmaWNhdGUtZGlhbG9nL2NlcnRpZmljYXRlLWRpYWxvZy5jb21wb25lbnQnXG5pbXBvcnQgeyBNYXRMZWdhY3lEaWFsb2cgYXMgTWF0RGlhbG9nIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvbGVnYWN5LWRpYWxvZydcbmltcG9ydCB7IGFuaW1hdGUsIHN0eWxlLCB0cmFuc2l0aW9uLCB0cmlnZ2VyIH0gZnJvbSAnQGFuZ3VsYXIvYW5pbWF0aW9ucydcbi8qIHRzbGludDpkaXNhYmxlKi9cbmltcG9ydCBfIGZyb20gJ2xvZGFzaCdcbmltcG9ydCBtb21lbnQgZnJvbSAnbW9tZW50J1xuaW1wb3J0IHsgQ2VydGlmaWNhdGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vLi4vc2VydmljZXMvY2VydGlmaWNhdGUuc2VydmljZSdcbmltcG9ydCB7IEFwcFRvY1NlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi8uLi9zZXJ2aWNlcy9hcHAtdG9jLnNlcnZpY2UnXG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJ1xuaW1wb3J0IHsgQ29udGVudExhbmd1YWdlU2VydmljZSB9IGZyb20gJ0BzdW5iaXJkLWNiL2NvbnN1bXB0aW9uJ1xuaW1wb3J0IHsgUmVzb3VyY2VEb3dubG9hZEhlbHBlclNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi8uLi9zZXJ2aWNlcy9yZXNvdXJjZS1kb3dubG9hZC1oZWxwZXIuc2VydmljZSdcbmltcG9ydCB7IE1hdExlZ2FjeVNuYWNrQmFyIGFzIE1hdFNuYWNrQmFyIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvbGVnYWN5LXNuYWNrLWJhcidcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnd3Mtd2lkZ2V0LWFwcC10b2MtY29udGVudC1jYXJkLXYyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2FwcC10b2MtY29udGVudC1jYXJkLXYyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vYXBwLXRvYy1jb250ZW50LWNhcmQtdjIuY29tcG9uZW50LnNjc3MnXSxcbiAgYW5pbWF0aW9uczogW1xuICAgIHRyaWdnZXIoJ3BhbmVsSW5PdXQnLCBbXG4gICAgICB0cmFuc2l0aW9uKCd2b2lkID0+IConLCBbXG4gICAgICAgIHN0eWxlKHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlWSgtMTAlKScsIG9wYWNpdHk6ICcwJyB9KSxcbiAgICAgICAgYW5pbWF0ZSgyNTApXG4gICAgICBdKSxcbiAgICAgIHRyYW5zaXRpb24oJyogPT4gdm9pZCcsIFtcbiAgICAgICAgYW5pbWF0ZSgyMDAsIHN0eWxlKHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlWSgtMTAlKScsIG9wYWNpdHk6ICcwJyB9KSlcbiAgICAgIF0pXG4gICAgXSlcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBBcHBUb2NDb250ZW50Q2FyZFYyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICBASW5wdXQoKSBjb250ZW50OiBOc0NvbnRlbnQuSUNvbnRlbnQgfCBudWxsID0gbnVsbFxuICBASW5wdXQoKSBleHBhbmRBbGwgPSBmYWxzZVxuICBASW5wdXQoKSByb290SWQhOiBzdHJpbmdcbiAgQElucHV0KCkgcm9vdENvbnRlbnRUeXBlITogc3RyaW5nXG4gIEBJbnB1dCgpIGZvclByZXZpZXcgPSBmYWxzZVxuICBASW5wdXQoKSBiYXRjaElkITogc3RyaW5nXG4gIEBJbnB1dCgpIGNvbXBvbmVudE5hbWU6IHN0cmluZyA9ICd0b2MnXG4gIEBJbnB1dCgpIGluZGV4ITogbnVtYmVyXG4gIEBJbnB1dCgpIHBhdGhTZXQhOiBhbnlcbiAgQElucHV0KCkgZXhwYW5kQWN0aXZlID0gdHJ1ZVxuICBASW5wdXQoKSBoaWVyYXJjaHlNYXBEYXRhOiBhbnkgPSB7fVxuICBASW5wdXQoKSBiYXRjaERhdGE6IC8qKk5zQ29udGVudC5JQmF0Y2hMaXN0UmVzcG9uc2UgKi8gYW55IHwgbnVsbCA9IG51bGxcbiAgQElucHV0KCkgaXNQcmVBc3Nlc3NtZW50ID0gZmFsc2VcbiAgQElucHV0KCkgYmFzZUNvbnRlbnRSZWFkRGF0YTogTnNDb250ZW50LklDb250ZW50IHwgbnVsbCA9IG51bGxcbiAgQElucHV0KCkgbWxDb3Vyc2U6IE5zQ29udGVudC5JQ29udGVudCB8IG51bGwgPSBudWxsXG4gIEBJbnB1dCgpIHBhcmVudE1pbGVzdG9uZUxvY2tlZCA9IGZhbHNlIC8vIFBhc3NlZCBmcm9tIHBhcmVudCB3aGVuIGluc2lkZSBhIGxvY2tlZCBtaWxlc3RvbmVcbiAgaGFzQ29udGVudFN0cnVjdHVyZSA9IGZhbHNlXG4gIGRvd25sb2FkQ2VydGlmaWNhdGVMb2FkaW5nID0gZmFsc2VcbiAgZW51bUNvbnRlbnRUeXBlcyA9IE5zQ29udGVudC5FRGlzcGxheUNvbnRlbnRUeXBlc1xuICBjb250ZW50U3RydWN0dXJlOiBOc0FwcFRvYy5JVG9jU3RydWN0dXJlID0ge1xuICAgIGFzc2Vzc21lbnQ6IDAsXG4gICAgZmluYWxUZXN0OiAwLFxuICAgIGNvdXJzZTogMCxcbiAgICBoYW5kc09uOiAwLFxuICAgIGludGVyYWN0aXZlVmlkZW86IDAsXG4gICAgbGVhcm5pbmdNb2R1bGU6IDAsXG4gICAgb3RoZXI6IDAsXG4gICAgcGRmOiAwLFxuICAgIHN1cnZleTogMCxcbiAgICBwb2RjYXN0OiAwLFxuICAgIHByYWN0aWNlVGVzdDogMCxcbiAgICBxdWl6OiAwLFxuICAgIHZpZGVvOiAwLFxuICAgIHdlYk1vZHVsZTogMCxcbiAgICB3ZWJQYWdlOiAwLFxuICAgIHlvdXR1YmU6IDAsXG4gICAgaW50ZXJhY3RpdmVjb250ZW50OiAwLFxuICAgIG9mZmxpbmVTZXNzaW9uOiAwLFxuICB9XG4gIGRlZmF1bHRUaHVtYm5haWwgPSAnJ1xuICB2aWV3Q2hpbGRyZW4gPSBmYWxzZVxuICBwcmltYXJ5Q2F0ZWdvcnkgPSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeVxuICBwYWdlU2Nyb2xsU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb24gfCBudWxsID0gbnVsbFxuICBoYXNobWFwVXBkYXRlZFN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uIHwgbnVsbCA9IG51bGxcbiAgYWNoaWV2ZW1lbnRMb2FkaW5nOiBib29sZWFuID0gZmFsc2VcbiAgLy8gQ2FjaGVkIGNvbXB1dGVkIHByb3BlcnRpZXMgZm9yIHBlcmZvcm1hbmNlIG9wdGltaXphdGlvblxuICBwcml2YXRlIF9jYWNoZWRJc0NvbGxlY3Rpb246IGJvb2xlYW4gPSBmYWxzZVxuICBwcml2YXRlIF9jYWNoZWRJc01vZHVsZTogYm9vbGVhbiA9IGZhbHNlXG4gIHByaXZhdGUgX2NhY2hlZElzUmVzb3VyY2U6IGJvb2xlYW4gPSBmYWxzZVxuICBwcml2YXRlIF9jYWNoZWRJc01pbGVzdG9uZTogYm9vbGVhbiA9IGZhbHNlXG4gIHByaXZhdGUgX2NhY2hlZElzTWlsZXN0b25lTG9ja2VkOiBib29sZWFuID0gZmFsc2VcbiAgcHJpdmF0ZSBfY2FjaGVkSXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQ6IGJvb2xlYW4gPSBmYWxzZVxuICBwcml2YXRlIF9jYWNoZWRJc0NvbnRlbnRVbmxvY2tlZDogYm9vbGVhbiA9IHRydWVcbiAgcHJpdmF0ZSBfY2FjaGVkQ2hlY2tGb3JDdXJhdGVkUHJvZ3JhbTogYm9vbGVhbiA9IGZhbHNlXG4gIHByaXZhdGUgX2NhY2hlZElzTWlsZXN0b25lQXNzZXNzbWVudDogYm9vbGVhbiA9IGZhbHNlXG4gIHByaXZhdGUgX2NhY2hlZElzTWlsZXN0b25lQXNzZXNzbWVudExvY2tlZDogYm9vbGVhbiA9IGZhbHNlXG4gIHByaXZhdGUgX2NhY2hlZFJlc291cmNlTGluazogeyB1cmw6IHN0cmluZzsgcXVlcnlQYXJhbXM6IHsgW2tleTogc3RyaW5nXTogYW55IH0gfSA9IHsgdXJsOiAnJywgcXVlcnlQYXJhbXM6IHt9IH1cbiAgcHJpdmF0ZSBfY2FjaGVJbml0aWFsaXplZDogYm9vbGVhbiA9IGZhbHNlXG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBldmVudHM6IEV2ZW50U2VydmljZSxcbiAgICBwcml2YXRlIGRpYWxvZzogTWF0RGlhbG9nLFxuICAgIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICBwcml2YXRlIGNlcnRpZmljYXRlU2VydmljZTogQ2VydGlmaWNhdGVTZXJ2aWNlLFxuICAgIHByaXZhdGUgYXBwVG9jU3ZjOiBBcHBUb2NTZXJ2aWNlLFxuICAgIHByaXZhdGUgY29udGVudExhbmdTdmM6IENvbnRlbnRMYW5ndWFnZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSByZXNvdXJjZURvd25sb2FkSGVscGVyU3ZjOiBSZXNvdXJjZURvd25sb2FkSGVscGVyU2VydmljZSwgICAgXG4gICAgcHJpdmF0ZSBjb25maWdTdmM6IENvbmZpZ3VyYXRpb25zU2VydmljZSxcbiAgICBwcml2YXRlIHNuYWNrQmFyOiBNYXRTbmFja0JhclxuICApIHsgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuZXZhbHVhdGVJbW1lZGlhdGVDaGlsZHJlblN0cnVjdHVyZSgpXG4gICAgdGhpcy5pbml0aWFsaXplQ29tcHV0ZWRQcm9wZXJ0aWVzKClcbiAgICAvLyB0aGlzLnJvdXRlLmRhdGEuc3Vic2NyaWJlKGRhdGEgPT4ge1xuICAgIC8vICAgICB0aGlzLmRlZmF1bHRUaHVtYm5haWwgPSBkYXRhLmNvbmZpZ0RhdGEuZGF0YS5sb2dvcy5kZWZhdWx0Q29udGVudFxuICAgIC8vICAgfVxuICAgIC8vIClcbiAgICB0aGlzLnJlc291cmNlU2Nyb2xsKClcbiAgICBcbiAgICAvLyBTdWJzY3JpYmUgdG8gaGFzaG1hcCB1cGRhdGVzIHRvIHJlY29tcHV0ZSBjYWNoZWQgcHJvcGVydGllcyB3aGVuIHByb2dyZXNzIGNoYW5nZXNcbiAgICB0aGlzLmhhc2htYXBVcGRhdGVkU3Vic2NyaXB0aW9uID0gdGhpcy5hcHBUb2NTdmMuaGFzaG1hcFVwZGF0ZWQkLnN1YnNjcmliZSgodXBkYXRlKSA9PiB7XG4gICAgICBpZiAodXBkYXRlICYmIHVwZGF0ZS5oYXNobWFwKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCfwn5SEIEhhc2htYXAgdXBkYXRlZCwgcmVjb21wdXRpbmcgY2FjaGVkIHByb3BlcnRpZXMgZm9yOicsIHRoaXMuY29udGVudD8uaWRlbnRpZmllcilcbiAgICAgICAgLy8gSU1QT1JUQU5UOiBVcGRhdGUgaGllcmFyY2h5TWFwRGF0YSB3aXRoIHRoZSBsYXRlc3QgaGFzaG1hcCBmcm9tIHRoZSBzZXJ2aWNlXG4gICAgICAgIC8vIFRoaXMgZW5zdXJlcyB0aGUgY29tcG9uZW50IHVzZXMgdGhlIHVwZGF0ZWQgZGF0YSwgbm90IHRoZSBzdGFsZSBASW5wdXQgcmVmZXJlbmNlXG4gICAgICAgIHRoaXMuaGllcmFyY2h5TWFwRGF0YSA9IHVwZGF0ZS5oYXNobWFwXG4gICAgICAgIHRoaXMuY29tcHV0ZUFsbENhY2hlZFByb3BlcnRpZXMoKVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZSBhbGwgY29tcHV0ZWQgcHJvcGVydGllcyBvbmNlIHRvIGF2b2lkIGV4cGVuc2l2ZSBnZXR0ZXIgY2FsY3VsYXRpb25zXG4gICAqIG9uIGV2ZXJ5IGNoYW5nZSBkZXRlY3Rpb24gY3ljbGVcbiAgICovXG4gIHByaXZhdGUgaW5pdGlhbGl6ZUNvbXB1dGVkUHJvcGVydGllcygpIHtcbiAgICB0aGlzLmNvbXB1dGVBbGxDYWNoZWRQcm9wZXJ0aWVzKClcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wdXRlIGFsbCBjYWNoZWQgcHJvcGVydGllcyBhdCBvbmNlIGZvciBwZXJmb3JtYW5jZSBvcHRpbWl6YXRpb25cbiAgICovXG4gIHByaXZhdGUgY29tcHV0ZUFsbENhY2hlZFByb3BlcnRpZXMoKSB7XG4gICAgaWYgKCF0aGlzLmNvbnRlbnQpIHtcbiAgICAgIHRoaXMuX2NhY2hlSW5pdGlhbGl6ZWQgPSBmYWxzZVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgY29udGVudElkID0gdGhpcy5jb250ZW50LmlkZW50aWZpZXJcbiAgICBjb25zdCBoYXNoRGF0YSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YSAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbY29udGVudElkXVxuXG4gICAgLy8gVXNlIGhhc2htYXAgZGF0YSBpZiBhdmFpbGFibGUgZm9yIHByZS1jb21wdXRlZCB2YWx1ZXNcbiAgICBpZiAoaGFzaERhdGEpIHtcbiAgICAgIHRoaXMuX2NhY2hlZElzQ29sbGVjdGlvbiA9IGhhc2hEYXRhLmlzQ29sbGVjdGlvbiAhPT0gdW5kZWZpbmVkID8gXG4gICAgICAgIGhhc2hEYXRhLmlzQ29sbGVjdGlvbiA6IHRoaXMuY29udGVudC5taW1lVHlwZSA9PT0gTnNDb250ZW50LkVNaW1lVHlwZXMuQ09MTEVDVElPTlxuICAgICAgdGhpcy5fY2FjaGVkSXNNb2R1bGUgPSBoYXNoRGF0YS5pc01vZHVsZSAhPT0gdW5kZWZpbmVkID8gXG4gICAgICAgIGhhc2hEYXRhLmlzTW9kdWxlIDogdGhpcy5jb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuTU9EVUxFXG4gICAgICB0aGlzLl9jYWNoZWRJc1Jlc291cmNlID0gaGFzaERhdGEuaXNSZXNvdXJjZSAhPT0gdW5kZWZpbmVkID8gXG4gICAgICAgIGhhc2hEYXRhLmlzUmVzb3VyY2UgOiB0aGlzLmNvbXB1dGVJc1Jlc291cmNlKClcbiAgICAgIHRoaXMuX2NhY2hlZElzTWlsZXN0b25lID0gaGFzaERhdGEuaXNNaWxlc3RvbmUgIT09IHVuZGVmaW5lZCA/IFxuICAgICAgICBoYXNoRGF0YS5pc01pbGVzdG9uZSA6IHRoaXMuY29tcHV0ZUlzTWlsZXN0b25lKClcbiAgICAgIHRoaXMuX2NhY2hlZElzTWlsZXN0b25lTG9ja2VkID0gaGFzaERhdGEuY29tcHV0ZWRJc0xvY2tlZCAhPT0gdW5kZWZpbmVkID8gXG4gICAgICAgIGhhc2hEYXRhLmNvbXB1dGVkSXNMb2NrZWQgOiB0aGlzLmNvbXB1dGVJc01pbGVzdG9uZUxvY2tlZCgpXG4gICAgICB0aGlzLl9jYWNoZWRJc1BhcmVudE1pbGVzdG9uZUxvY2tlZCA9IGhhc2hEYXRhLmlzUGFyZW50TWlsZXN0b25lTG9ja2VkICE9PSB1bmRlZmluZWQgPyBcbiAgICAgICAgaGFzaERhdGEuaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQgOiB0aGlzLmNvbXB1dGVJc1BhcmVudE1pbGVzdG9uZUxvY2tlZCgpXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEZhbGxiYWNrIHRvIGRpcmVjdCBjb21wdXRhdGlvbiBpZiBoYXNobWFwIG5vdCBhdmFpbGFibGVcbiAgICAgIHRoaXMuX2NhY2hlZElzQ29sbGVjdGlvbiA9IHRoaXMuY29udGVudC5taW1lVHlwZSA9PT0gTnNDb250ZW50LkVNaW1lVHlwZXMuQ09MTEVDVElPTlxuICAgICAgdGhpcy5fY2FjaGVkSXNNb2R1bGUgPSB0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5NT0RVTEVcbiAgICAgIHRoaXMuX2NhY2hlZElzUmVzb3VyY2UgPSB0aGlzLmNvbXB1dGVJc1Jlc291cmNlKClcbiAgICAgIHRoaXMuX2NhY2hlZElzTWlsZXN0b25lID0gdGhpcy5jb21wdXRlSXNNaWxlc3RvbmUoKVxuICAgICAgdGhpcy5fY2FjaGVkSXNNaWxlc3RvbmVMb2NrZWQgPSB0aGlzLmNvbXB1dGVJc01pbGVzdG9uZUxvY2tlZCgpXG4gICAgICB0aGlzLl9jYWNoZWRJc1BhcmVudE1pbGVzdG9uZUxvY2tlZCA9IHRoaXMuY29tcHV0ZUlzUGFyZW50TWlsZXN0b25lTG9ja2VkKClcbiAgICB9XG5cbiAgICB0aGlzLl9jYWNoZWRDaGVja0ZvckN1cmF0ZWRQcm9ncmFtID0gdGhpcy5jb21wdXRlQ2hlY2tGb3JDdXJhdGVkUHJvZ3JhbSgpXG4gICAgdGhpcy5fY2FjaGVkSXNDb250ZW50VW5sb2NrZWQgPSB0aGlzLmNvbXB1dGVJc0NvbnRlbnRVbmxvY2tlZCgpXG4gICAgdGhpcy5fY2FjaGVkSXNNaWxlc3RvbmVBc3Nlc3NtZW50ID0gdGhpcy5jb21wdXRlSXNNaWxlc3RvbmVBc3Nlc3NtZW50KClcbiAgICB0aGlzLl9jYWNoZWRJc01pbGVzdG9uZUFzc2Vzc21lbnRMb2NrZWQgPSB0aGlzLmNvbXB1dGVJc01pbGVzdG9uZUFzc2Vzc21lbnRMb2NrZWQoKVxuICAgIHRoaXMuX2NhY2hlZFJlc291cmNlTGluayA9IHRoaXMuY29tcHV0ZVJlc291cmNlTGluaygpXG4gICAgdGhpcy5fY2FjaGVJbml0aWFsaXplZCA9IHRydWVcbiAgfVxuXG4gIHByaXZhdGUgY29tcHV0ZUlzUmVzb3VyY2UoKTogYm9vbGVhbiB7XG4gICAgaWYgKCF0aGlzLmNvbnRlbnQpIHJldHVybiBmYWxzZVxuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5SRVNPVVJDRSB8fFxuICAgICAgdGhpcy5jb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuUFJBQ1RJQ0VfUkVTT1VSQ0UgfHxcbiAgICAgIHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgfHxcbiAgICAgIHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LkNPTVBfQVNTRVNTTUVOVFxuICAgIClcbiAgfVxuXG4gIHByaXZhdGUgY29tcHV0ZUlzTWlsZXN0b25lKCk6IGJvb2xlYW4ge1xuICAgIGlmICghdGhpcy5jb250ZW50KSByZXR1cm4gZmFsc2VcbiAgICBjb25zdCBwcmltYXJ5Q2F0ID0gdGhpcy5jb250ZW50LnByaW1hcnlDYXRlZ29yeSBhcyBzdHJpbmdcbiAgICBjb25zdCBjb3Vyc2VDYXQgPSB0aGlzLmNvbnRlbnQuY291cnNlQ2F0ZWdvcnkgYXMgc3RyaW5nXG4gICAgcmV0dXJuIHByaW1hcnlDYXQgPT09ICdNaWxlc3RvbmUnIHx8IGNvdXJzZUNhdCA9PT0gJ01pbGVzdG9uZSdcbiAgfVxuXG4gIHByaXZhdGUgY29tcHV0ZUNoZWNrRm9yQ3VyYXRlZFByb2dyYW0oKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMuY29udGVudCAmJiB0aGlzLmNvbnRlbnQucGFyZW50ICYmIHRoaXMuaGllcmFyY2h5TWFwRGF0YSAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbdGhpcy5jb250ZW50LnBhcmVudF0pIHtcbiAgICAgIGNvbnN0IHBhcmVudERhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbdGhpcy5jb250ZW50LnBhcmVudF1cbiAgICAgIHJldHVybiBwYXJlbnREYXRhICYmIHBhcmVudERhdGEucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5DVVJBVEVEX1BST0dSQU0gJiZcbiAgICAgICAgcGFyZW50RGF0YS5jb21wYXRpYmlsaXR5TGV2ZWwgPj0gNSAmJlxuICAgICAgICBwYXJlbnREYXRhLmNvbnRleHRMb2NraW5nVHlwZSA9PT0gTnNDb250ZW50LkVDb250ZXh0TG9ja2luZ1R5cGUuQ09VUlNFX0FTU0VTU01FTlRfT05MWVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIHByaXZhdGUgY29tcHV0ZUlzQ29udGVudFVubG9ja2VkKCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLl9jYWNoZWRDaGVja0ZvckN1cmF0ZWRQcm9ncmFtKSB7XG4gICAgICBpZiAodGhpcy5jb250ZW50ICYmIHRoaXMuY29udGVudC5wYXJlbnQgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhICYmIHRoaXMuaGllcmFyY2h5TWFwRGF0YVt0aGlzLmNvbnRlbnQucGFyZW50XSkge1xuICAgICAgICBjb25zdCBwYXJlbnREYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3RoaXMuY29udGVudC5wYXJlbnRdXG4gICAgICAgIGxldCBjb21wbGV0ZWRMZWFmTm9kZXM6IGFueVtdID0gW11cbiAgICAgICAgcGFyZW50RGF0YS5sZWFmTm9kZXMuZm9yRWFjaCgoX2VsZTogYW55KSA9PiB7XG4gICAgICAgICAgaWYgKHRoaXMuaGllcmFyY2h5TWFwRGF0YSAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbX2VsZV0pIHtcbiAgICAgICAgICAgIGNvbnN0IGNoaWxkRGF0YSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YVtfZWxlXVxuICAgICAgICAgICAgaWYgKGNoaWxkRGF0YSAmJiBjaGlsZERhdGEuY29tcGxldGlvblN0YXR1cyA9PT0gMikge1xuICAgICAgICAgICAgICBjb21wbGV0ZWRMZWFmTm9kZXMucHVzaChjaGlsZERhdGEpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICByZXR1cm4gY29tcGxldGVkTGVhZk5vZGVzLmxlbmd0aCA+PSBwYXJlbnREYXRhLmxlYWZOb2Rlc0NvdW50IC0gMVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICBwcml2YXRlIGNvbXB1dGVSZXNvdXJjZUxpbmsoKTogeyB1cmw6IHN0cmluZzsgcXVlcnlQYXJhbXM6IHsgW2tleTogc3RyaW5nXTogYW55IH0gfSB7XG4gICAgaWYgKHRoaXMuY29udGVudCkge1xuICAgICAgbGV0IG1pbWVUeXBlOiBhbnkgPSAnJ1xuICAgICAgaWYgKHRoaXMuY29udGVudCAmJiB0aGlzLmNvbnRlbnQuY291cnNlQ2F0ZWdvcnkgPT09ICdQcmUgRW5yb2xtZW50IEFzc2Vzc21lbnQnICYmXG4gICAgICAgIHRoaXMuY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5la3N0ZXAuY29udGVudC1jb2xsZWN0aW9uJ1xuICAgICAgKSB7XG4gICAgICAgIG1pbWVUeXBlID0gJ2FwcGxpY2F0aW9uL3ZuZC5zdW5iaXJkLnF1ZXN0aW9uc2V0J1xuICAgICAgICB0aGlzLmNvbnRlbnQubWltZVR5cGUgPSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5GSU5BTF9BU1NFU1NNRU5UXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtaW1lVHlwZSA9IHRoaXMuY29udGVudC5taW1lVHlwZVxuICAgICAgfVxuICAgICAgY29uc3Qgc2VsZWN0ZWRMYW5ndWFnZSA9IHRoaXMubWxDb3Vyc2UgPyB0aGlzLmNvbnRlbnRMYW5nU3ZjLmdldFNlbGVjdGVkTGFuZ3VhZ2UodGhpcy5tbENvdXJzZSkgOiB1bmRlZmluZWRcbiAgICAgIHJldHVybiB2aWV3ZXJSb3V0ZUdlbmVyYXRvcihcbiAgICAgICAgdGhpcy5jb250ZW50LmlkZW50aWZpZXIsXG4gICAgICAgIG1pbWVUeXBlLFxuICAgICAgICB0aGlzLmJhc2VDb250ZW50UmVhZERhdGE/LmlkZW50aWZpZXIgfHwgdGhpcy5yb290SWQsXG4gICAgICAgIHRoaXMuYmFzZUNvbnRlbnRSZWFkRGF0YT8uY29udGVudFR5cGUgfHwgdGhpcy5yb290Q29udGVudFR5cGUsXG4gICAgICAgIHRoaXMuZm9yUHJldmlldyxcbiAgICAgICAgdGhpcy5jb250ZW50LnByaW1hcnlDYXRlZ29yeSxcbiAgICAgICAgdGhpcy5iYXRjaElkLFxuICAgICAgICB0aGlzLmNvbnRlbnQ/Lm5hbWUgfHwgdGhpcy5iYXNlQ29udGVudFJlYWREYXRhPy5uYW1lLFxuICAgICAgICAoc2VsZWN0ZWRMYW5ndWFnZSA/IHNlbGVjdGVkTGFuZ3VhZ2UubGFuZ0lkIDogbnVsbCksXG4gICAgICAgIChzZWxlY3RlZExhbmd1YWdlID8gc2VsZWN0ZWRMYW5ndWFnZS5pZGVudGlmaWVyIDogbnVsbCksXG4gICAgICApXG4gICAgfVxuICAgIHJldHVybiB7IHVybDogJycsIHF1ZXJ5UGFyYW1zOiB7fSB9XG4gIH1cblxuICBwcml2YXRlIGNvbXB1dGVJc01pbGVzdG9uZUxvY2tlZCgpOiBib29sZWFuIHtcbiAgICAvLyBPbmx5IGFwcGx5IG1pbGVzdG9uZSBsb2NraW5nIGZvciBMZWFybmluZyBQYXRod2F5IGNvbnRlbnRcbiAgICBpZiAoIXRoaXMuYmFzZUNvbnRlbnRSZWFkRGF0YSB8fCB0aGlzLmJhc2VDb250ZW50UmVhZERhdGEuY291cnNlQ2F0ZWdvcnkgIT09ICdMZWFybmluZyBQYXRod2F5Jykge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLmNvbnRlbnQpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIC8vIENoZWNrIGlmIGN1cnJlbnQgY29udGVudCBpcyBhIE1pbGVzdG9uZVxuICAgIGlmICghdGhpcy5fY2FjaGVkSXNNaWxlc3RvbmUgJiYgIXRoaXMuY29tcHV0ZUlzTWlsZXN0b25lKCkpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIC8vIENoZWNrIGlmIGhhc2htYXAgaGFzIHByZS1jb21wdXRlZCBsb2NraW5nIHN0YXR1cyAocHJlZmVycmVkIC0gY29tcHV0ZWQgYnkgc2VydmljZSlcbiAgICBjb25zdCBoYXNoRGF0YSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YSAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbdGhpcy5jb250ZW50LmlkZW50aWZpZXJdXG4gICAgY29uc29sZS5sb2coYGNvbXB1dGVJc01pbGVzdG9uZUxvY2tlZCBmb3IgJHt0aGlzLmNvbnRlbnQuaWRlbnRpZmllcn0gKCR7dGhpcy5jb250ZW50Lm5hbWV9KTpgLCB7XG4gICAgICBoYXNoRGF0YSxcbiAgICAgIGNvbXB1dGVkSXNMb2NrZWQ6IGhhc2hEYXRhPy5jb21wdXRlZElzTG9ja2VkLFxuICAgICAgY29udGVudElzTG9ja2VkOiB0aGlzLmNvbnRlbnQuaXNMb2NrZWRcbiAgICB9KVxuICAgIFxuICAgIGlmIChoYXNoRGF0YSAmJiBoYXNoRGF0YS5jb21wdXRlZElzTG9ja2VkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBoYXNoRGF0YS5jb21wdXRlZElzTG9ja2VkXG4gICAgfVxuXG4gICAgLy8gSWYgbWlsZXN0b25lIGhhcyBpc0xvY2tlZCBmbGFnIGV4cGxpY2l0bHkgc2V0IHRvIGZhbHNlLCBpdCdzIHVubG9ja2VkXG4gICAgaWYgKHRoaXMuY29udGVudC5pc0xvY2tlZCA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIC8vIEZhbGxiYWNrOiBBbGwgbWlsZXN0b25lcyBhcmUgbG9ja2VkIGJ5IGRlZmF1bHQgdW50aWwgY29tcHV0ZWQgb3RoZXJ3aXNlXG4gICAgLy8gVGhpcyBlbnN1cmVzIHByb3BlciBsb2NraW5nIHVudGlsIHRoZSBoYXNobWFwIGlzIHVwZGF0ZWQgd2l0aCBwcm9ncmVzc1xuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICBwcml2YXRlIGNvbXB1dGVJc1BhcmVudE1pbGVzdG9uZUxvY2tlZCgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5wYXJlbnRNaWxlc3RvbmVMb2NrZWQpIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLmJhc2VDb250ZW50UmVhZERhdGEgfHwgdGhpcy5iYXNlQ29udGVudFJlYWREYXRhLmNvdXJzZUNhdGVnb3J5ICE9PSAnTGVhcm5pbmcgUGF0aHdheScpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIGlmICghdGhpcy5jb250ZW50IHx8ICF0aGlzLmhpZXJhcmNoeU1hcERhdGEpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIC8vIENoZWNrIGhhc2htYXAgZm9yIHByZS1jb21wdXRlZCB2YWx1ZVxuICAgIGNvbnN0IGhhc2hEYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3RoaXMuY29udGVudC5pZGVudGlmaWVyXVxuICAgIGlmIChoYXNoRGF0YSAmJiBoYXNoRGF0YS5pc1BhcmVudE1pbGVzdG9uZUxvY2tlZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gaGFzaERhdGEuaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWRcbiAgICB9XG5cbiAgICAvLyBUcmF2ZXJzZSB1cCB0aGUgaGllcmFyY2h5IHRvIGZpbmQgaWYgYW55IGFuY2VzdG9yIGlzIGEgbG9ja2VkIE1pbGVzdG9uZVxuICAgIGxldCBjdXJyZW50UGFyZW50SWQgPSB0aGlzLmNvbnRlbnQucGFyZW50XG4gICAgY29uc3QgbWF4RGVwdGggPSA1XG4gICAgbGV0IGRlcHRoID0gMFxuXG4gICAgd2hpbGUgKGN1cnJlbnRQYXJlbnRJZCAmJiBkZXB0aCA8IG1heERlcHRoKSB7XG4gICAgICBjb25zdCBwYXJlbnREYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2N1cnJlbnRQYXJlbnRJZF1cbiAgICAgIGlmIChwYXJlbnREYXRhKSB7XG4gICAgICAgIGlmICgocGFyZW50RGF0YS5pc01pbGVzdG9uZSB8fCBwYXJlbnREYXRhLnByaW1hcnlDYXRlZ29yeSA9PT0gJ01pbGVzdG9uZScgfHwgcGFyZW50RGF0YS5jb3Vyc2VDYXRlZ29yeSA9PT0gJ01pbGVzdG9uZScpICYmIFxuICAgICAgICAgICAgKHBhcmVudERhdGEuY29tcHV0ZWRJc0xvY2tlZCB8fCBwYXJlbnREYXRhLmlzTG9ja2VkKSkge1xuICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH1cbiAgICAgICAgY3VycmVudFBhcmVudElkID0gcGFyZW50RGF0YS5wYXJlbnRcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgICBkZXB0aCsrXG4gICAgfVxuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGN1cnJlbnQgY29udGVudCBpcyBhIE1JTEVTVE9ORSBhc3Nlc3NtZW50IChESVJFQ1QgY2hpbGQgb2YgYSBNaWxlc3RvbmUpXG4gICAqIElNUE9SVEFOVDogVGhpcyBzaG91bGQgTk9UIHJldHVybiB0cnVlIGZvciBjb3Vyc2UgYXNzZXNzbWVudHMgaW5zaWRlIGNvdXJzZXMgd2l0aGluIG1pbGVzdG9uZXNcbiAgICogT25seSBhc3Nlc3NtZW50cyB0aGF0IGFyZSBkaXJlY3QgY2hpbGRyZW4gb2YgbWlsZXN0b25lcyBzaG91bGQgYmUgbG9ja2VkIGJ5IG1pbGVzdG9uZSBsb2dpY1xuICAgKi9cbiAgcHJpdmF0ZSBjb21wdXRlSXNNaWxlc3RvbmVBc3Nlc3NtZW50KCk6IGJvb2xlYW4ge1xuICAgIGlmICghdGhpcy5iYXNlQ29udGVudFJlYWREYXRhIHx8IHRoaXMuYmFzZUNvbnRlbnRSZWFkRGF0YS5jb3Vyc2VDYXRlZ29yeSAhPT0gJ0xlYXJuaW5nIFBhdGh3YXknKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuY29udGVudCB8fCAhdGhpcy5oaWVyYXJjaHlNYXBEYXRhKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiB0aGlzIGlzIGFuIGFzc2Vzc21lbnQgdHlwZVxuICAgIC8vIE5vdGU6IEZJTkFMX0FTU0VTU01FTlQgbWFwcyB0byAnQ291cnNlIEFzc2Vzc21lbnQnIGluIHRoZSBlbnVtLCBub3QgJ0ZpbmFsIEFzc2Vzc21lbnQnXG4gICAgY29uc3QgaXNBc3Nlc3NtZW50ID0gXG4gICAgICB0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSAnQ291cnNlIEFzc2Vzc21lbnQnIHx8XG4gICAgICB0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSAnU3RhbmRhbG9uZSBBc3Nlc3NtZW50JyB8fFxuICAgICAgdGhpcy5jb250ZW50Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLnN1bmJpcmQucXVlc3Rpb25zZXQnIHx8XG4gICAgICB0aGlzLmNvbnRlbnQubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9xdWl6J1xuXG4gICAgaWYgKCFpc0Fzc2Vzc21lbnQpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIC8vIElNUE9SVEFOVDogT25seSByZXR1cm4gdHJ1ZSBpZiB0aGUgRElSRUNUIHBhcmVudCBpcyBhIG1pbGVzdG9uZVxuICAgIC8vIEFzc2Vzc21lbnRzIGluc2lkZSBjb3Vyc2VzIChncmFuZGNoaWxkcmVuIG9mIG1pbGVzdG9uZXMpIHNob3VsZCBOT1QgYmUgbG9ja2VkIGJ5IG1pbGVzdG9uZSBsb2dpY1xuICAgIC8vIFRoZXkgZm9sbG93IHRoZWlyIG93biBjb3Vyc2UncyBsb2NraW5nIHJ1bGVzXG4gICAgXG4gICAgLy8gR2V0IHRoZSBwYXJlbnQgZnJvbSBoYXNobWFwICh3aGljaCB3ZSBmaXhlZCB0byB0cmFjayBjb3JyZWN0IHBhcmVudC1jaGlsZCByZWxhdGlvbnNoaXBzKVxuICAgIC8vIG9yIGZhbGxiYWNrIHRvIGNvbnRlbnQucGFyZW50IGlmIGhhc2htYXAgZW50cnkgZG9lc24ndCBleGlzdFxuICAgIGNvbnN0IGNvbnRlbnRIYXNoRGF0YSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YVt0aGlzLmNvbnRlbnQuaWRlbnRpZmllcl1cbiAgICBjb25zdCBwYXJlbnRJZCA9IGNvbnRlbnRIYXNoRGF0YT8ucGFyZW50IHx8IHRoaXMuY29udGVudC5wYXJlbnRcbiAgICBcbiAgICBjb25zb2xlLmxvZyhg8J+UjSBjb21wdXRlSXNNaWxlc3RvbmVBc3Nlc3NtZW50IGZvciBcIiR7dGhpcy5jb250ZW50Lm5hbWV9XCIgKCR7dGhpcy5jb250ZW50LmlkZW50aWZpZXJ9KTpgLCB7XG4gICAgICBjb250ZW50SWQ6IHRoaXMuY29udGVudC5pZGVudGlmaWVyLFxuICAgICAgcHJpbWFyeUNhdGVnb3J5OiB0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5LFxuICAgICAgbWltZVR5cGU6IHRoaXMuY29udGVudC5taW1lVHlwZSxcbiAgICAgIGNvbnRlbnRQYXJlbnQ6IHRoaXMuY29udGVudC5wYXJlbnQsXG4gICAgICBoYXNobWFwUGFyZW50OiBjb250ZW50SGFzaERhdGE/LnBhcmVudCxcbiAgICAgIHJlc29sdmVkUGFyZW50SWQ6IHBhcmVudElkLFxuICAgICAgaGFzUGFyZW50RGF0YTogISF0aGlzLmhpZXJhcmNoeU1hcERhdGFbcGFyZW50SWRdXG4gICAgfSlcbiAgICBcbiAgICBpZiAocGFyZW50SWQgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3BhcmVudElkXSkge1xuICAgICAgY29uc3QgcGFyZW50RGF0YSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YVtwYXJlbnRJZF1cbiAgICAgIFxuICAgICAgY29uc29sZS5sb2coYCAgIFBhcmVudCBkZXRhaWxzOmAsIHtcbiAgICAgICAgcGFyZW50SWQ6IHBhcmVudElkLFxuICAgICAgICBwYXJlbnROYW1lOiBwYXJlbnREYXRhPy5uYW1lLFxuICAgICAgICBwYXJlbnRQcmltYXJ5Q2F0ZWdvcnk6IHBhcmVudERhdGE/LnByaW1hcnlDYXRlZ29yeSxcbiAgICAgICAgcGFyZW50SXNNaWxlc3RvbmU6IHBhcmVudERhdGE/LmlzTWlsZXN0b25lLFxuICAgICAgICBwYXJlbnRDb3Vyc2VDYXRlZ29yeTogcGFyZW50RGF0YT8uY291cnNlQ2F0ZWdvcnksXG4gICAgICB9KVxuICAgICAgXG4gICAgICAvLyBDaGVjayBpZiBESVJFQ1QgcGFyZW50IGlzIGEgbWlsZXN0b25lIC0gT05MWSB0aGlzIGNhc2VcbiAgICAgIGNvbnN0IGlzUGFyZW50TWlsZXN0b25lID0gcGFyZW50RGF0YS5pc01pbGVzdG9uZSB8fCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50RGF0YS5wcmltYXJ5Q2F0ZWdvcnkgPT09ICdNaWxlc3RvbmUnIHx8IFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnREYXRhLmNvdXJzZUNhdGVnb3J5ID09PSAnTWlsZXN0b25lJ1xuICAgICAgXG4gICAgICBpZiAoaXNQYXJlbnRNaWxlc3RvbmUpIHtcbiAgICAgICAgY29uc29sZS5sb2coYCAgIOKchSBSZXN1bHQ6IElTIGEgbWlsZXN0b25lIGFzc2Vzc21lbnQgKGRpcmVjdCBjaGlsZCBvZiBtaWxlc3RvbmUpYClcbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgIH1cbiAgICAgIFxuICAgICAgY29uc29sZS5sb2coYCAgIOKdjCBSZXN1bHQ6IE5PVCBhIG1pbGVzdG9uZSBhc3Nlc3NtZW50IChwYXJlbnQgaXMgJHtwYXJlbnREYXRhLnByaW1hcnlDYXRlZ29yeX0sIG5vdCBhIE1pbGVzdG9uZSlgKVxuICAgICAgLy8gRE8gTk9UIGNoZWNrIGdyYW5kcGFyZW50IC0gY291cnNlIGFzc2Vzc21lbnRzIGluc2lkZSBjb3Vyc2VzIHdpdGhpbiBtaWxlc3RvbmVzXG4gICAgICAvLyBzaG91bGQgTk9UIGJlIHRyZWF0ZWQgYXMgbWlsZXN0b25lIGFzc2Vzc21lbnRzXG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS5sb2coYCAgIOKaoO+4jyAgTm8gcGFyZW50IGRhdGEgZm91bmQgZm9yICR7cGFyZW50SWR9YClcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBtaWxlc3RvbmUgYXNzZXNzbWVudCBzaG91bGQgYmUgbG9ja2VkXG4gICAqIEFzc2Vzc21lbnQgaXMgbG9ja2VkIGlmOlxuICAgKiAxLiBJdCdzIGFuIGFzc2Vzc21lbnQgdGhhdCBpcyBhIERJUkVDVCBjaGlsZCBvZiBhIG1pbGVzdG9uZVxuICAgKiAyLiBUaGUgcGFyZW50IG1pbGVzdG9uZSBpcyB1bmxvY2tlZCAob3RoZXJ3aXNlIGhhbmRsZWQgYnkgcGFyZW50IG1pbGVzdG9uZSBsb2NrKVxuICAgKiAzLiBOT1QgYWxsIG1hbmRhdG9yeSBjb3Vyc2VzIGluIHRoZSBzYW1lIG1pbGVzdG9uZSBhcmUgY29tcGxldGVkXG4gICAqL1xuICBwcml2YXRlIGNvbXB1dGVJc01pbGVzdG9uZUFzc2Vzc21lbnRMb2NrZWQoKTogYm9vbGVhbiB7XG4gICAgLy8gQ1JJVElDQUw6IE9ubHkgYXBwbHkgbWlsZXN0b25lIGFzc2Vzc21lbnQgbG9ja2luZyBmb3IgTGVhcm5pbmcgUGF0aHdheSBjb250ZW50XG4gICAgLy8gUmVndWxhciBjb3Vyc2VzIHNob3VsZCBORVZFUiBoYXZlIHRoZWlyIGFzc2Vzc21lbnRzIGxvY2tlZCBieSBtaWxlc3RvbmUgbG9naWNcbiAgICBpZiAoIXRoaXMuYmFzZUNvbnRlbnRSZWFkRGF0YSB8fCB0aGlzLmJhc2VDb250ZW50UmVhZERhdGEuY291cnNlQ2F0ZWdvcnkgIT09ICdMZWFybmluZyBQYXRod2F5Jykge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy8gT25seSBhcHBseSB0byBhc3Nlc3NtZW50cyB0aGF0IGFyZSBESVJFQ1QgY2hpbGRyZW4gb2YgbWlsZXN0b25lc1xuICAgIGNvbnN0IGlzTWlsZXN0b25lQXNzZXNzbWVudCA9IHRoaXMuX2NhY2hlZElzTWlsZXN0b25lQXNzZXNzbWVudCB8fCB0aGlzLmNvbXB1dGVJc01pbGVzdG9uZUFzc2Vzc21lbnQoKVxuICAgIFxuICAgIGNvbnNvbGUubG9nKGDwn5SSIGNvbXB1dGVJc01pbGVzdG9uZUFzc2Vzc21lbnRMb2NrZWQgZm9yIFwiJHt0aGlzLmNvbnRlbnQ/Lm5hbWV9XCI6YCwge1xuICAgICAgaXNNaWxlc3RvbmVBc3Nlc3NtZW50LFxuICAgICAgX2NhY2hlZElzTWlsZXN0b25lQXNzZXNzbWVudDogdGhpcy5fY2FjaGVkSXNNaWxlc3RvbmVBc3Nlc3NtZW50LFxuICAgICAgY291cnNlQ2F0ZWdvcnk6IHRoaXMuYmFzZUNvbnRlbnRSZWFkRGF0YT8uY291cnNlQ2F0ZWdvcnksXG4gICAgfSlcbiAgICBcbiAgICBpZiAoIWlzTWlsZXN0b25lQXNzZXNzbWVudCkge1xuICAgICAgY29uc29sZS5sb2coYPCflJMgXCIke3RoaXMuY29udGVudD8ubmFtZX1cIiBOT1QgbG9ja2VkIC0gbm90IGEgbWlsZXN0b25lIGFzc2Vzc21lbnRgKVxuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgaGFzaG1hcCBoYXMgcHJlLWNvbXB1dGVkIGFzc2Vzc21lbnQgbG9ja2luZyBzdGF0dXNcbiAgICBjb25zdCBoYXNoRGF0YSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YSAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbdGhpcy5jb250ZW50Py5pZGVudGlmaWVyIHx8ICcnXVxuICAgIGlmIChoYXNoRGF0YSAmJiBoYXNoRGF0YS5pc0Fzc2Vzc21lbnRMb2NrZWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGhhc2hEYXRhLmlzQXNzZXNzbWVudExvY2tlZFxuICAgIH1cblxuICAgIC8vIElmIGFscmVhZHkgY29tcGxldGVkLCBkb24ndCBsb2NrXG4gICAgaWYgKHRoaXMuY29udGVudCAmJiAodGhpcy5jb250ZW50LmNvbXBsZXRpb25TdGF0dXMgPT09IDIgfHwgXG4gICAgICAgICh0aGlzLmNvbnRlbnQuY29tcGxldGlvblBlcmNlbnRhZ2UgJiYgdGhpcy5jb250ZW50LmNvbXBsZXRpb25QZXJjZW50YWdlID49IDEwMCkpKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICAvLyBGb3IgbWlsZXN0b25lIGFzc2Vzc21lbnRzLCB0aGUgcGFyZW50IElTIHRoZSBtaWxlc3RvbmUgKHZlcmlmaWVkIGJ5IGNvbXB1dGVJc01pbGVzdG9uZUFzc2Vzc21lbnQpXG4gICAgLy8gVXNlIGhhc2htYXAncyBwYXJlbnQgd2hpY2ggaGFzIGNvcnJlY3QgcGFyZW50LWNoaWxkIHJlbGF0aW9uc2hpcHNcbiAgICBjb25zdCBjb250ZW50SGFzaERhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGEgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3RoaXMuY29udGVudD8uaWRlbnRpZmllciB8fCAnJ11cbiAgICBjb25zdCBtaWxlc3RvbmVJZCA9IGNvbnRlbnRIYXNoRGF0YT8ucGFyZW50IHx8IHRoaXMuY29udGVudD8ucGFyZW50XG4gICAgXG4gICAgaWYgKCFtaWxlc3RvbmVJZCB8fCAhdGhpcy5oaWVyYXJjaHlNYXBEYXRhKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gICAgXG4gICAgY29uc3QgbWlsZXN0b25lID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW21pbGVzdG9uZUlkXVxuICAgIFxuICAgIGlmICghbWlsZXN0b25lKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gICAgXG4gICAgLy8gSWYgdGhlIHBhcmVudCBtaWxlc3RvbmUgaXRzZWxmIGlzIGxvY2tlZCwgZG9uJ3QgYWRkIGFkZGl0aW9uYWwgbG9ja2luZ1xuICAgIC8vICh0aGUgcGFyZW50IGxvY2sgd2lsbCBoYW5kbGUgaXQpXG4gICAgaWYgKG1pbGVzdG9uZS5jb21wdXRlZElzTG9ja2VkIHx8IG1pbGVzdG9uZS5pc0xvY2tlZCkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgYWxsIG1hbmRhdG9yeSBDT1VSU0VTIGluIHRoZSBtaWxlc3RvbmUgYXJlIGNvbXBsZXRlZFxuICAgIC8vIE5vdGU6IE9ubHkgY2hlY2tpbmcgY291cnNlcyB0aGF0IGFyZSBkaXJlY3QgY2hpbGRyZW4gb2YgdGhlIG1pbGVzdG9uZVxuICAgIGxldCBtYW5kYXRvcnlDb3VudCA9IDBcbiAgICBsZXQgY29tcGxldGVkTWFuZGF0b3J5Q291bnQgPSAwXG5cbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyh0aGlzLmhpZXJhcmNoeU1hcERhdGEpKSB7XG4gICAgICBjb25zdCBpdGVtID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2tleV1cblxuICAgICAgLy8gT25seSBjaGVjayBpdGVtcyB0aGF0IGFyZSBkaXJlY3QgY2hpbGRyZW4gb2YgdGhpcyBtaWxlc3RvbmVcbiAgICAgIGlmIChpdGVtLnBhcmVudCAhPT0gbWlsZXN0b25lSWQpIGNvbnRpbnVlXG5cbiAgICAgIC8vIE9ubHkgY291bnQgY291cnNlcyAobm90IGFzc2Vzc21lbnRzLCBub3Qgb3RoZXIgdHlwZXMpXG4gICAgICBpZiAoaXRlbS5wcmltYXJ5Q2F0ZWdvcnkgIT09ICdDb3Vyc2UnICYmICFpdGVtLmlzQ29sbGVjdGlvbikgY29udGludWVcbiAgICAgIFxuICAgICAgLy8gU2tpcCBpZiB0aGlzIGlzIGFuIGFzc2Vzc21lbnRcbiAgICAgIGNvbnN0IGlzSXRlbUFzc2Vzc21lbnQgPVxuICAgICAgICBpdGVtLnByaW1hcnlDYXRlZ29yeSA9PT0gJ0NvdXJzZSBBc3Nlc3NtZW50JyB8fFxuICAgICAgICBpdGVtLnByaW1hcnlDYXRlZ29yeSA9PT0gJ0ZpbmFsIEFzc2Vzc21lbnQnIHx8XG4gICAgICAgIGl0ZW0ucHJpbWFyeUNhdGVnb3J5ID09PSAnU3RhbmRhbG9uZSBBc3Nlc3NtZW50JyB8fFxuICAgICAgICBpdGVtLm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLnN1bmJpcmQucXVlc3Rpb25zZXQnXG4gICAgICBpZiAoaXNJdGVtQXNzZXNzbWVudCkgY29udGludWVcblxuICAgICAgLy8gQnkgZGVmYXVsdCwgY291cnNlcyBhcmUgbWFuZGF0b3J5IHVubGVzcyBleHBsaWNpdGx5IG1hcmtlZCBhcyBvcHRpb25hbFxuICAgICAgaWYgKGl0ZW0uaXNNYW5kYXRvcnkgIT09IGZhbHNlKSB7XG4gICAgICAgIG1hbmRhdG9yeUNvdW50KytcbiAgICAgICAgY29uc3QgaXNDb21wbGV0ZWQgPSBpdGVtLmNvbXBsZXRpb25TdGF0dXMgPT09IDIgfHwgaXRlbS5zdGF0dXMgPT09IDIgfHwgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtLmNvbXBsZXRpb25QZXJjZW50YWdlID49IDEwMCB8fCBpdGVtLnByb2dyZXNzID49IDEwMFxuICAgICAgICBpZiAoaXNDb21wbGV0ZWQpIHtcbiAgICAgICAgICBjb21wbGV0ZWRNYW5kYXRvcnlDb3VudCsrXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBJZiB0aGVyZSBhcmUgbm8gbWFuZGF0b3J5IGNvdXJzZXMsIGFzc2Vzc21lbnQgaXMgdW5sb2NrZWRcbiAgICBpZiAobWFuZGF0b3J5Q291bnQgPT09IDApIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIC8vIExvY2sgYXNzZXNzbWVudCBpZiBub3QgYWxsIG1hbmRhdG9yeSBjb3Vyc2VzIGFyZSBjb21wbGV0ZWRcbiAgICBjb25zdCBhbGxNYW5kYXRvcnlDb21wbGV0ZSA9IGNvbXBsZXRlZE1hbmRhdG9yeUNvdW50ID49IG1hbmRhdG9yeUNvdW50XG4gICAgcmV0dXJuICFhbGxNYW5kYXRvcnlDb21wbGV0ZVxuICB9XG5cbiAgLy8gRk9SIFJJR0hUIFNJREUgUkVTT1VSQ0UgU0NST0xMIE9OIFRPQyBQQUdFXG4gIHJlc291cmNlU2Nyb2xsKCkge1xuICAgIHRoaXMucGFnZVNjcm9sbFN1YnNjcmlwdGlvbiA9IHRoaXMuYXBwVG9jU3ZjLnVwZGF0ZVBhZ2VTY3JvbGwuc3Vic2NyaWJlKCh2YWx1ZTogYm9vbGVhbikgPT4ge1xuICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIHRoaXMuc2Nyb2xsVmlldygpXG4gICAgICAgIH0sIDcwMClcbiAgICAgIH1cbiAgICB9KVxuICB9XG4gIC8vIFRPIFVQREFURSBSRVNPVVJDRSBCRUhBVk9VUiBTVUJKRUNUIEZPUiBSRVNPVVJDRSBTQ1JPTExcbiAgY2hhbmdlUmVzb3VyY2UoKSB7XG4gICAgdGhpcy5hcHBUb2NTdmMuZ2V0UGFnZVNjcm9sbC5uZXh0KHRydWUpXG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgbGV0IHNob3VsZFJlY29tcHV0ZUNhY2hlID0gZmFsc2VcblxuICAgIGZvciAoY29uc3QgcHJvcGVydHkgaW4gY2hhbmdlcykge1xuICAgICAgaWYgKHByb3BlcnR5ID09PSAnZXhwYW5kQWxsJykge1xuICAgICAgICB0aGlzLnZpZXdDaGlsZHJlbiA9IHRoaXMuZXhwYW5kQWxsXG4gICAgICB9XG4gICAgICBpZiAocHJvcGVydHkgPT09ICdwYXRoU2V0JyAmJiBjaGFuZ2VzWydwYXRoU2V0J10pIHtcbiAgICAgICAgbGV0IGN1cnJlbnRWYWx1ZSA9IGNoYW5nZXNbJ3BhdGhTZXQnXS5jdXJyZW50VmFsdWVcbiAgICAgICAgbGV0IHByZXZpb3VzVmFsdWUgPSBjaGFuZ2VzWydwYXRoU2V0J10ucHJldmlvdXNWYWx1ZVxuICAgICAgICBpZiAoY3VycmVudFZhbHVlICYmIHByZXZpb3VzVmFsdWUpIHtcbiAgICAgICAgICBjb25zdCBlcVNldCA9ICh4czogYW55LCB5czogYW55KSA9PlxuICAgICAgICAgICAgeHMuc2l6ZSA9PT0geXMuc2l6ZSAmJlxuICAgICAgICAgICAgWy4uLnhzXS5ldmVyeSgoeCkgPT4geXMuaGFzKHgpKVxuICAgICAgICAgIGlmICghZXFTZXQocHJldmlvdXNWYWx1ZSwgY3VycmVudFZhbHVlKSkgeyB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gaWYocHJldmlvdXNWYWx1ZSA9PT0gdW5kZWZpbmVkKXtcbiAgICAgICAgLy8gICBzZXRUaW1lb3V0KCgpPT57XG4gICAgICAgIC8vICAgfSw3MDApXG4gICAgICAgIC8vIH1cbiAgICAgIH1cbiAgICAgIC8vIHRoaXMuYXBwVG9jU3ZjLmdldFBhZ2VTY3JvbGwubmV4dCh0cnVlKVxuXG4gICAgICBpZiAocHJvcGVydHkgPT09ICdoaWVyYXJjaHlNYXBEYXRhJykge1xuICAgICAgICBpZiAoXy5pc0VtcHR5KGNoYW5nZXNbJ2hpZXJhcmNoeU1hcERhdGEnXS5jdXJyZW50VmFsdWUpKSB7XG4gICAgICAgICAgLy8gdGhpcy5sb2FkaW5nT3ZlcmFsbFBSb2dyZXNzID0gdHJ1ZVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmICh0aGlzLmNvbnRlbnQpIHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlQ2hpbGRQYXJlbnRNYXAodGhpcy5jb250ZW50LmlkZW50aWZpZXIpXG4gICAgICAgICAgfVxuICAgICAgICAgIHNob3VsZFJlY29tcHV0ZUNhY2hlID0gdHJ1ZVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFJlY29tcHV0ZSBjYWNoZSB3aGVuIGNyaXRpY2FsIGlucHV0cyBjaGFuZ2VcbiAgICAgIGlmIChwcm9wZXJ0eSA9PT0gJ2NvbnRlbnQnIHx8IHByb3BlcnR5ID09PSAnYmFzZUNvbnRlbnRSZWFkRGF0YScgfHwgXG4gICAgICAgICAgcHJvcGVydHkgPT09ICdiYXRjaElkJyB8fCBwcm9wZXJ0eSA9PT0gJ2ZvclByZXZpZXcnIHx8IFxuICAgICAgICAgIHByb3BlcnR5ID09PSAncGFyZW50TWlsZXN0b25lTG9ja2VkJyB8fCBwcm9wZXJ0eSA9PT0gJ21sQ291cnNlJykge1xuICAgICAgICBzaG91bGRSZWNvbXB1dGVDYWNoZSA9IHRydWVcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSZWNvbXB1dGUgYWxsIGNhY2hlZCBwcm9wZXJ0aWVzIGlmIG5lZWRlZFxuICAgIGlmIChzaG91bGRSZWNvbXB1dGVDYWNoZSkge1xuICAgICAgdGhpcy5jb21wdXRlQWxsQ2FjaGVkUHJvcGVydGllcygpXG4gICAgfVxuICAgIC8vIGNvbnNvbGUubG9nKCdwcmUgYXNzZXNzbWVudCBjb250ZW50LS0tJywgdGhpcy5jb250ZW50KVxuICAgIC8vIGNvbnNvbGUubG9nKCd0aGlzLmhpZXJhcmNoeU1hcERhdGEtLS0nLCB0aGlzLmhpZXJhcmNoeU1hcERhdGEpXG4gIH1cblxuICBjaGVjayhjb250ZW50OiBhbnkpIHtcbiAgICBpZiAodGhpcy5leHBhbmRBY3RpdmUpIHtcbiAgICAgIGNvbnRlbnQudmlld0NoaWxkcmVuID0gdGhpcy5wYXRoU2V0ICYmIHRoaXMucGF0aFNldC5oYXMoY29udGVudC5pZGVudGlmaWVyKSB8fCBjb250ZW50LnZpZXdDaGlsZHJlblxuICAgIH1cbiAgICByZXR1cm4gY29udGVudC52aWV3Q2hpbGRyZW5cbiAgfVxuXG4gIGdldCBpc0NvbGxlY3Rpb24oKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMuX2NhY2hlSW5pdGlhbGl6ZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLl9jYWNoZWRJc0NvbGxlY3Rpb25cbiAgICB9XG4gICAgaWYgKHRoaXMuY29udGVudCkge1xuICAgICAgcmV0dXJuIHRoaXMuY29udGVudC5taW1lVHlwZSA9PT0gTnNDb250ZW50LkVNaW1lVHlwZXMuQ09MTEVDVElPTlxuICAgIH1cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIGdldCBpc01vZHVsZSgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5fY2FjaGVJbml0aWFsaXplZCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZElzTW9kdWxlXG4gICAgfVxuICAgIGlmICh0aGlzLmNvbnRlbnQpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5NT0RVTEVcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBwdWJsaWMgY2hlY2tNb2R1bGUoY29udGVudDogTnNDb250ZW50LklDb250ZW50IHwgbnVsbCk6IGJvb2xlYW4ge1xuICAgIGlmIChjb250ZW50KSB7XG4gICAgICByZXR1cm4gY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk1PRFVMRVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIGNoZWNrSXNNb2R1bGUoY29udGVudDogYW55KTogYm9vbGVhbiB7XG4gICAgaWYgKGNvbnRlbnQpIHtcbiAgICAgIHJldHVybiBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuTU9EVUxFXG4gICAgfVxuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgZ2V0IGlzQmF0Y2hJblByb2dlc3MoKSB7XG4gICAgaWYgKHRoaXMuYmF0Y2hEYXRhICYmICh0aGlzLmJhdGNoRGF0YS5jb250ZW50ICYmIHRoaXMuYmF0Y2hEYXRhLmNvbnRlbnQubGVuZ3RoKSAmJiB0aGlzLmJhdGNoRGF0YS5lbnJvbGxlZCkge1xuICAgICAgY29uc3QgYmF0Y2hEYXRhID0gdGhpcy5iYXRjaERhdGEuY29udGVudFswXVxuICAgICAgaWYgKGJhdGNoRGF0YSAmJiBiYXRjaERhdGEuZW5kRGF0ZSkge1xuICAgICAgICBjb25zdCBub3cgPSBtb21lbnQoKS5mb3JtYXQoJ1lZWVktTU0tREQnKVxuICAgICAgICBjb25zdCBzdGFydERhdGUgPSBtb21lbnQoYmF0Y2hEYXRhLnN0YXJ0RGF0ZSkuZm9ybWF0KCdZWVlZLU1NLUREJylcbiAgICAgICAgY29uc3QgZW5kRGF0ZSA9IGJhdGNoRGF0YS5lbmREYXRlID8gbW9tZW50KGJhdGNoRGF0YS5lbmREYXRlKS5mb3JtYXQoJ1lZWVktTU0tREQnKSA6IG5vd1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIC8vIGJhdGNoLnN0YXR1cyAmJlxuICAgICAgICAgIG1vbWVudChzdGFydERhdGUpLmlzU2FtZU9yQmVmb3JlKG5vdylcbiAgICAgICAgICAmJiBtb21lbnQoZW5kRGF0ZSkuaXNTYW1lT3JBZnRlcihub3cpXG4gICAgICAgIClcbiAgICAgIH0gcmV0dXJuIHRydWVcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBnZXQgaXNSZXNvdXJjZSgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5fY2FjaGVJbml0aWFsaXplZCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZElzUmVzb3VyY2VcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY29tcHV0ZUlzUmVzb3VyY2UoKVxuICB9XG5cbiAgZ2V0IHJlc291cmNlTGluaygpOiB7IHVybDogc3RyaW5nOyBxdWVyeVBhcmFtczogeyBba2V5OiBzdHJpbmddOiBhbnkgfSB9IHtcbiAgICBpZiAodGhpcy5fY2FjaGVJbml0aWFsaXplZCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZFJlc291cmNlTGlua1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jb21wdXRlUmVzb3VyY2VMaW5rKClcbiAgfVxuXG4gIHB1YmxpYyBwcm9ncmVzc0NvbG9yKCk6IHN0cmluZyB7XG4gICAgLy8gaWYgKHRoaXMuY3VycmVudFByb2dyZXNzIDw9IDMwKSB7XG4gICAgLy8gICByZXR1cm4gJyNEMTM5MjQnXG4gICAgLy8gfSBpZiAodGhpcy5jdXJyZW50UHJvZ3Jlc3MgPiAzMCAmJiB0aGlzLmN1cnJlbnRQcm9ncmVzcyA8PSA3MCkge1xuICAgIC8vICAgcmV0dXJuICcjRTk5RTM4J1xuICAgIC8vIH1cbiAgICAvLyBpZiAodGhpcy5jdXJyZW50UHJvZ3Jlc3MgPiA3MCAmJiB0aGlzLmN1cnJlbnRQcm9ncmVzcyA8PSAxMDApIHtcbiAgICAvLyAgIHJldHVybiAnIzFEODkyMydcbiAgICAvLyB9XG5cbiAgICByZXR1cm4gJyMxRDg5MjMnXG4gIH1cbiAgcHVibGljIHByb2dyZXNzQ29sb3IyKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuICcjZjI3ZDAwJ1xuICB9XG5cbiAgcHJpdmF0ZSBldmFsdWF0ZUltbWVkaWF0ZUNoaWxkcmVuU3RydWN0dXJlKCkge1xuICAgIGlmICh0aGlzLmNvbnRlbnQgJiYgdGhpcy5jb250ZW50LmNoaWxkcmVuICYmIHRoaXMuY29udGVudC5jaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgIHRoaXMuY29udGVudC5jaGlsZHJlbi5mb3JFYWNoKChjaGlsZDogTnNDb250ZW50LklDb250ZW50KSA9PiB7XG4gICAgICAgIGlmIChjaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LkNPVVJTRSkge1xuICAgICAgICAgIHRoaXMuY29udGVudFN0cnVjdHVyZS5jb3Vyc2UgKz0gMVxuICAgICAgICB9IGVsc2UgaWYgKGNoaWxkLnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuS05PV0xFREdFX0FSVElGQUNUKSB7XG4gICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLm90aGVyICs9IDFcbiAgICAgICAgfSBlbHNlIGlmIChjaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk1PRFVMRSkge1xuICAgICAgICAgIHRoaXMuY29udGVudFN0cnVjdHVyZS5sZWFybmluZ01vZHVsZSArPSAxXG4gICAgICAgIH0gZWxzZSBpZiAoY2hpbGQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5PRkZMSU5FX1NFU1NJT04pIHtcbiAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUub2ZmbGluZVNlc3Npb24gKz0gMVxuICAgICAgICB9IGVsc2UgaWYgKGNoaWxkLnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuUkVTT1VSQ0UpIHtcbiAgICAgICAgICBzd2l0Y2ggKGNoaWxkLm1pbWVUeXBlKSB7XG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLkhBTkRTX09OOlxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUuaGFuZHNPbiArPSAxXG4gICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLk1QMzpcbiAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLnBvZGNhc3QgKz0gMVxuICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5NUDQ6XG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLk0zVTg6XG4gICAgICAgICAgICAgIHRoaXMuY29udGVudFN0cnVjdHVyZS52aWRlbyArPSAxXG4gICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLklOVEVSQUNUSU9OOlxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUuaW50ZXJhY3RpdmVWaWRlbyArPSAxXG4gICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLlBERjpcbiAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLnBkZiArPSAxXG4gICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLk9GRkxJTkVfU0VTU0lPTjpcbiAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLm9mZmxpbmVTZXNzaW9uICs9IDFcbiAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuU1VSVkVZOlxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUuc3VydmV5ICs9IDFcbiAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuSFRNTDpcbiAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLndlYlBhZ2UgKz0gMVxuICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5RVUlaOlxuICAgICAgICAgICAgICBpZiAoY2hpbGQucmVzb3VyY2VUeXBlID09PSAnQXNzZXNzbWVudCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUuYXNzZXNzbWVudCArPSAxXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLnF1aXogKz0gMVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLlBSQUNUSUNFX1JFU09VUkNFOlxuICAgICAgICAgICAgICAvLyBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLkZJTkFMX0FTU0VTU01FTlQ6XG4gICAgICAgICAgICAgIC8vIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuUFJBQ1RJQ0VfUkVTT1VSQ0U6XG4gICAgICAgICAgICAgIHRoaXMuY29udGVudFN0cnVjdHVyZS5wcmFjdGljZVRlc3QgKz0gMVxuICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5XRUJfTU9EVUxFOlxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUud2ViTW9kdWxlICs9IDFcbiAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuWU9VVFVCRTpcbiAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLnlvdXR1YmUgKz0gMVxuICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLm90aGVyICs9IDFcbiAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICAgIGZvciAoY29uc3Qga2V5IGluIHRoaXMuY29udGVudFN0cnVjdHVyZSkge1xuICAgICAgaWYgKHRoaXMuY29udGVudFN0cnVjdHVyZVtrZXldID4gMCkge1xuICAgICAgICB0aGlzLmhhc0NvbnRlbnRTdHJ1Y3R1cmUgPSB0cnVlXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2V0IGNvbnRleHRQYXRoKCkge1xuICAgIHJldHVybiB7XG4gICAgICBjb250ZXh0SWQ6IHRoaXMucm9vdElkLFxuICAgICAgY29udGV4dFBhdGg6IHRoaXMucm9vdENvbnRlbnRUeXBlLFxuICAgICAgYmF0Y2hJZDogdGhpcy5iYXRjaElkLFxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBjb250ZW50VHJhY2tCeShfaW5kZXg6IG51bWJlciwgY29udGVudDogTnNDb250ZW50LklDb250ZW50KSB7XG4gICAgaWYgKCFjb250ZW50KSB7XG4gICAgICByZXR1cm4gbnVsbFxuICAgIH1cbiAgICByZXR1cm4gY29udGVudC5pZGVudGlmaWVyXG4gIH1cblxuICBwdWJsaWMgcmFpc2VUZWxlbWV0cnkoKSB7XG4gICAgLy8gaWYgKHRoaXMuZm9yUHJldmlldykgeyByZXR1cm4gfVxuICAgIGlmICh0aGlzLmNvbnRlbnQpIHtcbiAgICAgIHRoaXMuZXZlbnRzLnJhaXNlSW50ZXJhY3RUZWxlbWV0cnkoXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiAnY2xpY2snLFxuICAgICAgICAgIHN1YlR5cGU6IGBjYXJkLXRvY0NvbnRlbnRDYXJkYCxcbiAgICAgICAgICAvLyBpZDogdGhpcy5jb250ZW50LmlkZW50aWZpZXIgfHwgJycsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAvLyBjb250ZW50SWQ6IHRoaXMuY29udGVudC5pZGVudGlmaWVyIHx8ICcnLFxuICAgICAgICAgIC8vIGNvbnRlbnRUeXBlOiB0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5LFxuICAgICAgICAgIGlkOiB0aGlzLmNvbnRlbnQuaWRlbnRpZmllciB8fCAnJyxcbiAgICAgICAgICB0eXBlOiB0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5LFxuICAgICAgICAgIHJvbGx1cDoge1xuICAgICAgICAgICAgbDE6IHRoaXMucm9vdElkIHx8ICcnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdmVyOiBgJHt0aGlzLmNvbnRlbnQudmVyc2lvbn0keycnfWAsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBwYWdlSWRFeHQ6IGAke18uY2FtZWxDYXNlKHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkpfS1jYXJkYCxcbiAgICAgICAgICBtb2R1bGU6IF8uY2FtZWxDYXNlKHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkpLFxuICAgICAgICB9KVxuICAgIH1cbiAgfVxuICBnZXQgaXNBbGxvd2VkKCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLmNvbnRlbnQpIHtcbiAgICAgIHJldHVybiAhKE5zQ29udGVudC5VTl9TVVBQT1JURURfREFUQV9UWVBFU19GT1JfTk9OX0JBVENIX1VTRVJTLmluZGV4T2YodGhpcy5jb250ZW50Lm1pbWVUeXBlKSA+PSAwKVxuICAgIH0gcmV0dXJuIGZhbHNlXG4gIH1cblxuICBnZXQgaXNFbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICBnZXQgaXNFbnJvbGxlZCgpOiBib29sZWFuIHtcbiAgICAvLyBDaGVjayBib3RoIGJhdGNoSWQgYW5kIGJhdGNoRGF0YS5lbnJvbGxlZCB0byBzdXBwb3J0IExlYXJuaW5nIFBhdGh3YXlzXG4gICAgLy8gd2hlcmUgYmF0Y2hJZCBtaWdodCBub3QgYmUgZGlyZWN0bHkgc2V0IGJ1dCB1c2VyIGlzIGVucm9sbGVkIGluIGNvdXJzZXMgd2l0aGluIHRoZSBwYXRod2F5XG4gICAgcmV0dXJuIHRoaXMuYmF0Y2hJZCA/IHRydWUgOiAodGhpcy5iYXRjaERhdGE/LmVucm9sbGVkIHx8IGZhbHNlKVxuICB9XG5cbiAgdXBkYXRlQ2hpbGRQYXJlbnRNYXAoaWRlbnRpZmllcjogc3RyaW5nKSB7XG4gICAgaWYgKHRoaXMuaGllcmFyY2h5TWFwRGF0YSAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl0pIHtcbiAgICAgIGxldCBsb2NhbENvbnRlbnREYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2lkZW50aWZpZXJdXG4gICAgICBpZiAoXG4gICAgICAgICEobG9jYWxDb250ZW50RGF0YS5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LlJFU09VUkNFXG4gICAgICAgICAgfHwgbG9jYWxDb250ZW50RGF0YS5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFXG4gICAgICAgICAgfHwgbG9jYWxDb250ZW50RGF0YS5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlRcbiAgICAgICAgICB8fCBsb2NhbENvbnRlbnREYXRhLnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuQ09NUF9BU1NFU1NNRU5UKVxuICAgICAgKSB7XG4gICAgICAgIC8vIHJlYWwgcGVyY2VudCBsb2dpY1xuICAgICAgICAvLyBjb25zdCB0b3RhbCA9IGxvY2FsQ29udGVudERhdGEubGVhZk5vZGVzLnJlZHVjZSgoc3VtOiBudW1iZXIsIGNoaWxkSWQ6IHN0cmluZykgPT4ge1xuICAgICAgICAvLyAgIHJldHVybiBzdW0gKyBOdW1iZXIodGhpcy5oaWVyYXJjaHlNYXBEYXRhW2NoaWxkSWRdLmNvbXBsZXRpb25QZXJjZW50YWdlIHx8IDApXG4gICAgICAgIC8vIH0sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKVxuICAgICAgICAvLyBjb25zb2xlLmxvZygndG90YWwgJywgdG90YWwpXG4gICAgICAgIC8vIGlmKHRvdGFsID4gMCkge1xuICAgICAgICAvLyAgIHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXVsnY29tcGxldGlvblBlcmNlbnRhZ2UnXSA9IHRvdGFsIC8gXy50b0ludGVnZXIoXy5nZXQodGhpcy5oaWVyYXJjaHlNYXBEYXRhW2lkZW50aWZpZXJdLCAnbGVhZk5vZGVzQ291bnQnKSlcbiAgICAgICAgLy8gfVxuICAgICAgICBpZiAobG9jYWxDb250ZW50RGF0YS5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk1PRFVMRSkge1xuICAgICAgICAgIHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXVsnZHVyYXRpb24nXSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXS5sZWFmTm9kZXMucmVkdWNlKFxuICAgICAgICAgICAgKHN1bTogYW55LCBjaGlsZElEOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgaWYgKHRoaXMuaGllcmFyY2h5TWFwRGF0YSAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbY2hpbGRJRF0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc3VtICsgTnVtYmVyKHRoaXMuaGllcmFyY2h5TWFwRGF0YVtjaGlsZElEXS5kdXJhdGlvbiB8fCB0aGlzLmhpZXJhcmNoeU1hcERhdGFbY2hpbGRJRF0uZXhwZWN0ZWREdXJhdGlvbiB8fCAwKVxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIH0sIDApXG4gICAgICAgIH1cbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGVcbiAgICAgICAgY29uc3QgY29tcGxldGVkSXRlbXMgPSBfLmZpbHRlcih0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl0ubGVhZk5vZGVzLCByID0+ICh0aGlzLmhpZXJhcmNoeU1hcERhdGFbcl0gJiYgKHRoaXMuaGllcmFyY2h5TWFwRGF0YVtyXS5jb21wbGV0aW9uU3RhdHVzID09PSAyIHx8IHRoaXMuaGllcmFyY2h5TWFwRGF0YVtyXS5jb21wbGV0aW9uUGVyY2VudGFnZSA9PT0gMTAwKSkpXG4gICAgICAgIGNvbnN0IHRvdGFsQ291bnQgPSBfLnRvSW50ZWdlcihfLmdldCh0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl0sICdsZWFmTm9kZXNDb3VudCcpKSB8fCAxXG4gICAgICAgIHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXVsnY29tcGxldGlvblBlcmNlbnRhZ2UnXSA9IE51bWJlcigoKGNvbXBsZXRlZEl0ZW1zLmxlbmd0aCAvIHRvdGFsQ291bnQpICogMTAwKS50b0ZpeGVkKCkpXG4gICAgICAgIHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXVsnY29tcGxldGlvblN0YXR1cyddID0gKHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXS5jb21wbGV0aW9uUGVyY2VudGFnZSA+PSAxMDApID8gMiA6IDFcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl1cbiAgICB9XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICBnZXRDb21wbGV0aW9uUGVyY2VudGFnZShpZGVudGlmaWVyOiBzdHJpbmcpIHtcbiAgICAvLyBjb25zb2xlLmxvZygnZ2V0Q29tcGxldGlvblBlcmNlbnRhZ2UnLCBpZGVudGlmaWVyKVxuICAgIC8vIGNvbnNvbGUubG9nKCd0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl0gOiAnLCB0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl0pXG4gICAgLy8gY29uc3QgaXRlbSA9IHRoaXMudXBkYXRlQ2hpbGRQYXJlbnRNYXAoaWRlbnRpZmllcilcbiAgICBsZXQgcGVyY2VudCA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YSAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl0gJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2lkZW50aWZpZXJdLmNvbXBsZXRpb25QZXJjZW50YWdlIHx8IDBcbiAgICByZXR1cm4gdGhpcy5yb3VuZElmRGVjaW1hbChwZXJjZW50KVxuICB9XG5cbiAgcm91bmRJZkRlY2ltYWwodmFsdWU6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHBhcnNlRmxvYXQodmFsdWUudG9GaXhlZCgyKSlcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlXG4gIH1cblxuXG4gIGdldENvbXBsZXRpb25TdGF0dXMoaWRlbnRpZmllcjogc3RyaW5nKSB7XG4gICAgLy8gY29uc29sZS5sb2coJ2dldENvbXBsZXRpb25TdGF0dXMnKVxuICAgIC8vIGNvbnN0IGl0ZW0gPSB0aGlzLnVwZGF0ZUNoaWxkUGFyZW50TWFwKGlkZW50aWZpZXIpXG4gICAgcmV0dXJuIHRoaXMuaGllcmFyY2h5TWFwRGF0YSAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl0gJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2lkZW50aWZpZXJdLmNvbXBsZXRpb25TdGF0dXNcbiAgfVxuXG4gIG9wZW5DZXJ0aWZpY2F0ZURpYWxvZyhjZXJ0RGF0YTogYW55KSB7XG4gICAgY29uc3QgY2V0ID0gY2VydERhdGFcbiAgICB0aGlzLmRpYWxvZy5vcGVuKENlcnRpZmljYXRlRGlhbG9nQ29tcG9uZW50LCB7XG4gICAgICAvLyBoZWlnaHQ6ICc0MDBweCcsXG4gICAgICB3aWR0aDogJzEzMDBweCcsXG4gICAgICBkYXRhOiB7IGNldCB9LFxuICAgICAgLy8gcGFuZWxDbGFzczogJ2N1c3RvbS1kaWFsb2ctY29udGFpbmVyJyxcbiAgICB9KVxuICB9XG4gIHNjcm9sbFZpZXcoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGxldCBlcnJvckZpZWxkOiBhbnkgPSB0aGlzLnJlbmRlcmVyLnNlbGVjdFJvb3RFbGVtZW50KCcucmVzb3VyY2UtY29udGFpbmVyIC5yZXNvdXJjZS1hY3RpdmUnKVxuICAgICAgaWYgKGVycm9yRmllbGQpIHtcbiAgICAgICAgZXJyb3JGaWVsZC5zY3JvbGxJbnRvVmlldyh7IGJlaGF2aW9yOiBcInNtb290aFwiLCBibG9jazogXCJzdGFydFwiLCBpbmxpbmU6IFwibmVhcmVzdFwiIH0pXG4gICAgICB9XG4gICAgICBpZiAodGhpcy5jb21wb25lbnROYW1lID09PSAndG9jJykge1xuICAgICAgICBpZiAoZXJyb3JGaWVsZCkge1xuICAgICAgICAgIGNvbnN0IHJlY3QgPSBlcnJvckZpZWxkLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG4gICAgICAgICAgaWYgKHJlY3QudG9wIC0gNDIwID4gMCkge1xuICAgICAgICAgICAgd2luZG93LnNjcm9sbCg0MjAsIHJlY3QudG9wIC0gMTQ4KVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuYXBwVG9jU3ZjLmdldFBhZ2VTY3JvbGwubmV4dChmYWxzZSlcbiAgICAgIH0sIDcwMClcblxuICAgICAgLy8gZWxzZSB7XG4gICAgICAvLyAgIGVycm9yRmllbGQuc2Nyb2xsSW50b1ZpZXcoeyBiZWhhdmlvcjogXCJzbW9vdGhcIiwgYmxvY2s6IFwic3RhcnRcIiwgaW5saW5lOiBcIm5lYXJlc3RcIiB9KTtcbiAgICAgIC8vICAgY29uc3QgcmVjdCA9IGVycm9yRmllbGQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAvLyAgIGVycm9yRmllbGQuc2Nyb2xsKDAscmVjdC50b3AtNTYpXG4gICAgICAvLyB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgfVxuICB9XG5cbiAgZG93bmxvYWRDZXJ0aWZpY2F0ZShjZXJ0aWZpY2F0ZURhdGE6IGFueSkge1xuICAgIHRoaXMuZXZlbnRzLnJhaXNlSW50ZXJhY3RUZWxlbWV0cnkoXG4gICAgICB7XG4gICAgICAgIHR5cGU6IFdzRXZlbnRzLkVudW1JbnRlcmFjdFR5cGVzLkNMSUNLLFxuICAgICAgICBpZDogJ3ZpZXctY2VydGlmaWNhdGUnLFxuICAgICAgICBzdWJUeXBlOiBXc0V2ZW50cy5FbnVtSW50ZXJhY3RTdWJUeXBlcy5DRVJUSUZJQ0FURSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGlkOiBjZXJ0aWZpY2F0ZURhdGEsICAgLy8gaWQgb2YgdGhlIGNlcnRpZmljYXRlXG4gICAgICAgIHR5cGU6IFdzRXZlbnRzLkVudW1JbnRlcmFjdFN1YlR5cGVzLkNFUlRJRklDQVRFLFxuICAgICAgfSlcbiAgICBpZiAoY2VydGlmaWNhdGVEYXRhKSB7XG4gICAgICB0aGlzLmRvd25sb2FkQ2VydGlmaWNhdGVMb2FkaW5nID0gdHJ1ZVxuICAgICAgbGV0IGNlcnREYXRhOiBhbnkgPSBjZXJ0aWZpY2F0ZURhdGFcbiAgICAgIHRoaXMuY2VydGlmaWNhdGVTZXJ2aWNlLmRvd25sb2FkQ2VydGlmaWNhdGVfdjIoY2VydERhdGEpLnN1YnNjcmliZSgocmVzOiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy5kb3dubG9hZENlcnRpZmljYXRlTG9hZGluZyA9IGZhbHNlXG4gICAgICAgIGNvbnN0IGNldCA9IHJlcy5yZXN1bHQucHJpbnRVcmlcbiAgICAgICAgdGhpcy5kaWFsb2cub3BlbihDZXJ0aWZpY2F0ZURpYWxvZ0NvbXBvbmVudCwge1xuICAgICAgICAgIHdpZHRoOiAnMTMwMHB4JyxcbiAgICAgICAgICBkYXRhOiB7IGNldCwgY2VydElkOiBjZXJ0RGF0YS5pZGVudGlmaWVyIH0sXG4gICAgICAgIH0pXG4gICAgICB9KVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRvd25sb2FkQ2VydGlmaWNhdGVMb2FkaW5nID0gZmFsc2VcbiAgICB9XG4gIH1cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgaWYgKHRoaXMuaGFzaG1hcFVwZGF0ZWRTdWJzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMuaGFzaG1hcFVwZGF0ZWRTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKVxuICAgIH1cbiAgICBpZiAodGhpcy5wYWdlU2Nyb2xsU3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLnBhZ2VTY3JvbGxTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKVxuICAgIH1cbiAgfVxuXG4gIGdldCBjaGVja0ZvckN1cmF0ZWRQcm9ncmFtKCkge1xuICAgIGlmICh0aGlzLl9jYWNoZUluaXRpYWxpemVkKSB7XG4gICAgICByZXR1cm4gdGhpcy5fY2FjaGVkQ2hlY2tGb3JDdXJhdGVkUHJvZ3JhbVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jb21wdXRlQ2hlY2tGb3JDdXJhdGVkUHJvZ3JhbSgpXG4gIH1cblxuICBnZXQgaXNDb250ZW50VW5sb2NrZWQoKSB7XG4gICAgaWYgKHRoaXMuX2NhY2hlSW5pdGlhbGl6ZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLl9jYWNoZWRJc0NvbnRlbnRVbmxvY2tlZFxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jb21wdXRlSXNDb250ZW50VW5sb2NrZWQoKVxuICB9XG5cbiAgZ2V0IGlzUGFyZW50TWlsZXN0b25lTG9ja2VkKCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLl9jYWNoZUluaXRpYWxpemVkKSB7XG4gICAgICByZXR1cm4gdGhpcy5fY2FjaGVkSXNQYXJlbnRNaWxlc3RvbmVMb2NrZWRcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY29tcHV0ZUlzUGFyZW50TWlsZXN0b25lTG9ja2VkKClcbiAgfVxuXG4gIGdldCBpc01pbGVzdG9uZUxvY2tlZCgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5fY2FjaGVJbml0aWFsaXplZCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZElzTWlsZXN0b25lTG9ja2VkXG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNvbXB1dGVJc01pbGVzdG9uZUxvY2tlZCgpXG4gIH1cblxuICBnZXQgaXNNaWxlc3RvbmVBc3Nlc3NtZW50KCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLl9jYWNoZUluaXRpYWxpemVkKSB7XG4gICAgICByZXR1cm4gdGhpcy5fY2FjaGVkSXNNaWxlc3RvbmVBc3Nlc3NtZW50XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNvbXB1dGVJc01pbGVzdG9uZUFzc2Vzc21lbnQoKVxuICB9XG5cbiAgZ2V0IGlzTWlsZXN0b25lQXNzZXNzbWVudExvY2tlZCgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5fY2FjaGVJbml0aWFsaXplZCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZElzTWlsZXN0b25lQXNzZXNzbWVudExvY2tlZFxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jb21wdXRlSXNNaWxlc3RvbmVBc3Nlc3NtZW50TG9ja2VkKClcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhIG1pbGVzdG9uZSdzIG1hbmRhdG9yeSBjb3Vyc2VzIGFuZCBhc3Nlc3NtZW50IGFyZSBjb21wbGV0ZWQuXG4gICAqIExvb2tzIGF0IHRoZSBjb250ZW50IGhpZXJhcmNoeSB0byBmaW5kIGNoaWxkcmVuIG9mIHRoZSBtaWxlc3RvbmUuXG4gICAqL1xuICBwcml2YXRlIGNoZWNrTWlsZXN0b25lQ29udGVudENvbXBsZXRpb24obWlsZXN0b25lSWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmICghdGhpcy5iYXNlQ29udGVudFJlYWREYXRhIHx8ICF0aGlzLmJhc2VDb250ZW50UmVhZERhdGEuY2hpbGRyZW4gfHwgIXRoaXMuaGllcmFyY2h5TWFwRGF0YSkge1xuICAgICAgLy8gRmFsbGJhY2s6IFRyeSB0byBmaW5kIGFzc2Vzc21lbnQgY29tcGxldGlvbiBpbiBoYXNobWFwIGZvciB0aGlzIG1pbGVzdG9uZVxuICAgICAgcmV0dXJuIHRoaXMuY2hlY2tNaWxlc3RvbmVBc3Nlc3NtZW50Q29tcGxldGlvbihtaWxlc3RvbmVJZClcbiAgICB9XG5cbiAgICAvLyBGaW5kIHRoZSBtaWxlc3RvbmUgaW4gdGhlIGNvbnRlbnQgaGllcmFyY2h5XG4gICAgY29uc3QgbWlsZXN0b25lQ29udGVudCA9IHRoaXMuZmluZENvbnRlbnRJbkhpZXJhcmNoeSh0aGlzLmJhc2VDb250ZW50UmVhZERhdGEsIG1pbGVzdG9uZUlkKVxuICAgIGlmICghbWlsZXN0b25lQ29udGVudCB8fCAhbWlsZXN0b25lQ29udGVudC5jaGlsZHJlbikge1xuICAgICAgcmV0dXJuIHRoaXMuY2hlY2tNaWxlc3RvbmVBc3Nlc3NtZW50Q29tcGxldGlvbihtaWxlc3RvbmVJZClcbiAgICB9XG5cbiAgICAvLyBDaGVjayBhbGwgbWFuZGF0b3J5IGNvdXJzZXMgYW5kIGFzc2Vzc21lbnRzXG4gICAgbGV0IGFsbE1hbmRhdG9yeUNvbXBsZXRlID0gdHJ1ZVxuICAgIGxldCBoYXNBc3Nlc3NtZW50ID0gZmFsc2VcbiAgICBsZXQgYXNzZXNzbWVudENvbXBsZXRlID0gZmFsc2VcblxuICAgIG1pbGVzdG9uZUNvbnRlbnQuY2hpbGRyZW4uZm9yRWFjaCgoY2hpbGQ6IGFueSkgPT4ge1xuICAgICAgY29uc3QgY2hpbGREYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2NoaWxkLmlkZW50aWZpZXJdXG4gICAgICBjb25zdCBpc0Fzc2Vzc21lbnQgPSBjaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgPT09ICdDb3Vyc2UgQXNzZXNzbWVudCcgfHxcbiAgICAgICAgY2hpbGQuY291cnNlQ2F0ZWdvcnkgPT09ICdDb3Vyc2UgQXNzZXNzbWVudCcgfHxcbiAgICAgICAgY2hpbGQucHJpbWFyeUNhdGVnb3J5ID09PSAnRmluYWwgQXNzZXNzbWVudCdcbiAgICAgIGNvbnN0IGlzTWFuZGF0b3J5ID0gY2hpbGQubWFuZGF0b3J5ID09PSB0cnVlIHx8IGNoaWxkLm9wdGlvbmFsUmVhZGluZyAhPT0gdHJ1ZVxuXG4gICAgICBpZiAoaXNBc3Nlc3NtZW50KSB7XG4gICAgICAgIGhhc0Fzc2Vzc21lbnQgPSB0cnVlXG4gICAgICAgIGlmIChjaGlsZERhdGEgJiYgKGNoaWxkRGF0YS5jb21wbGV0aW9uU3RhdHVzID09PSAyIHx8IGNoaWxkRGF0YS5jb21wbGV0aW9uUGVyY2VudGFnZSA+PSAxMDApKSB7XG4gICAgICAgICAgYXNzZXNzbWVudENvbXBsZXRlID0gdHJ1ZVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGlzTWFuZGF0b3J5KSB7XG4gICAgICAgIC8vIENoZWNrIGlmIG1hbmRhdG9yeSBjb250ZW50IGlzIGNvbXBsZXRlZFxuICAgICAgICBpZiAoIWNoaWxkRGF0YSB8fCAoY2hpbGREYXRhLmNvbXBsZXRpb25TdGF0dXMgIT09IDIgJiYgY2hpbGREYXRhLmNvbXBsZXRpb25QZXJjZW50YWdlIDwgMTAwKSkge1xuICAgICAgICAgIGFsbE1hbmRhdG9yeUNvbXBsZXRlID0gZmFsc2VcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pXG5cbiAgICBjb25zb2xlLmxvZygnTWlsZXN0b25lIGNvbnRlbnQgY2hlY2s6JywgeyBhbGxNYW5kYXRvcnlDb21wbGV0ZSwgaGFzQXNzZXNzbWVudCwgYXNzZXNzbWVudENvbXBsZXRlIH0pXG5cbiAgICAvLyBNaWxlc3RvbmUgaXMgY29tcGxldGUgaWYgYXNzZXNzbWVudCBpcyBjb21wbGV0ZSAobWFuZGF0b3J5IGNvdXJzZXMgb3B0aW9uYWwgYmFzZWQgb24gcmVxdWlyZW1lbnRzKVxuICAgIHJldHVybiBoYXNBc3Nlc3NtZW50ID8gYXNzZXNzbWVudENvbXBsZXRlIDogYWxsTWFuZGF0b3J5Q29tcGxldGVcbiAgfVxuXG4gIC8qKlxuICAgKiBGYWxsYmFjazogQ2hlY2sgaWYgZW5vdWdoIGFzc2Vzc21lbnRzIGFyZSBjb21wbGV0ZWQgdG8gdW5sb2NrIHRoaXMgbWlsZXN0b25lLlxuICAgKiBGb3IgbWlsZXN0b25lIGF0IGluZGV4IE4sIHdlIG5lZWQgYXQgbGVhc3QgTiBjb21wbGV0ZWQgYXNzZXNzbWVudHMuXG4gICAqIEUuZy4sIEZvciBNMiAoaW5kZXggMSksIHdlIG5lZWQgMSBjb21wbGV0ZWQgYXNzZXNzbWVudCAoTTEncyBhc3Nlc3NtZW50KVxuICAgKiAgICAgICBGb3IgTTMgKGluZGV4IDIpLCB3ZSBuZWVkIDIgY29tcGxldGVkIGFzc2Vzc21lbnRzIChNMSdzIGFuZCBNMidzKVxuICAgKi9cbiAgcHJpdmF0ZSBjaGVja01pbGVzdG9uZUFzc2Vzc21lbnRDb21wbGV0aW9uKG1pbGVzdG9uZUlkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBpZiAoIXRoaXMuaGllcmFyY2h5TWFwRGF0YSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy8gRXh0cmFjdCBtaWxlc3RvbmUgbnVtYmVyIGZyb20gSUQgKE0xIC0+IDEsIE0yIC0+IDIsIGV0Yy4pXG4gICAgY29uc3QgbWlsZXN0b25lTnVtID0gcGFyc2VJbnQobWlsZXN0b25lSWQucmVwbGFjZSgvXFxEL2csICcnKSkgfHwgMFxuICAgIGNvbnN0IHJlcXVpcmVkQ29tcGxldGVkQXNzZXNzbWVudHMgPSBtaWxlc3RvbmVOdW0gLSAxIC8vIEZvciBNMiwgbmVlZCAxOyBmb3IgTTMsIG5lZWQgMlxuXG4gICAgY29uc29sZS5sb2coYE1pbGVzdG9uZSAke21pbGVzdG9uZUlkfSAobnVtOiAke21pbGVzdG9uZU51bX0pIHJlcXVpcmVzICR7cmVxdWlyZWRDb21wbGV0ZWRBc3Nlc3NtZW50c30gY29tcGxldGVkIGFzc2Vzc21lbnRzYClcblxuICAgIGlmIChyZXF1aXJlZENvbXBsZXRlZEFzc2Vzc21lbnRzIDw9IDApIHtcbiAgICAgIHJldHVybiB0cnVlIC8vIEZpcnN0IG1pbGVzdG9uZSwgbm8gcmVxdWlyZW1lbnRzXG4gICAgfVxuXG4gICAgLy8gQ291bnQgY29tcGxldGVkIENvdXJzZSBBc3Nlc3NtZW50cyB0aGF0IGFyZSBJTlNJREUgbWlsZXN0b25lcyAoaGF2ZSBhIHBhcmVudClcbiAgICAvLyBFeGNsdWRlIHByZS1lbnJvbGxtZW50IGFzc2Vzc21lbnRzIGF0IHRoZSByb290IGxldmVsIChubyBwYXJlbnQgb3IgcGFyZW50IGlzIExlYXJuaW5nIFBhdGh3YXkpXG4gICAgbGV0IGNvbXBsZXRlZE1pbGVzdG9uZUFzc2Vzc21lbnRDb3VudCA9IDBcbiAgICBjb25zdCBsZWFybmluZ1BhdGh3YXlJZCA9IHRoaXMuYmFzZUNvbnRlbnRSZWFkRGF0YT8uaWRlbnRpZmllclxuXG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXModGhpcy5oaWVyYXJjaHlNYXBEYXRhKSkge1xuICAgICAgY29uc3QgaXRlbSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YVtrZXldXG5cbiAgICAgIC8vIENoZWNrIGlmIGl0J3MgYSBjb21wbGV0ZWQgQ291cnNlIEFzc2Vzc21lbnRcbiAgICAgIGlmICgoaXRlbS5wcmltYXJ5Q2F0ZWdvcnkgPT09ICdDb3Vyc2UgQXNzZXNzbWVudCcgfHwgaXRlbS5jb3Vyc2VDYXRlZ29yeSA9PT0gJ0NvdXJzZSBBc3Nlc3NtZW50JykgJiZcbiAgICAgICAgKGl0ZW0uY29tcGxldGlvblN0YXR1cyA9PT0gMiB8fCBpdGVtLmNvbXBsZXRpb25QZXJjZW50YWdlID49IDEwMCkpIHtcblxuICAgICAgICAvLyBDaGVjayBpZiB0aGlzIGFzc2Vzc21lbnQgaGFzIGEgcGFyZW50IChtZWFuaW5nIGl0J3MgaW5zaWRlIGEgY291cnNlL21pbGVzdG9uZSwgbm90IGF0IHJvb3QgbGV2ZWwpXG4gICAgICAgIC8vIEFsc28gZXhjbHVkZSBpZiBwYXJlbnQgaXMgdGhlIExlYXJuaW5nIFBhdGh3YXkgaXRzZWxmIChwcmUtZW5yb2xsbWVudCBhc3Nlc3NtZW50KVxuICAgICAgICBjb25zdCBoYXNQYXJlbnQgPSBpdGVtLnBhcmVudCAmJiBpdGVtLnBhcmVudCAhPT0gbGVhcm5pbmdQYXRod2F5SWRcblxuICAgICAgICBpZiAoaGFzUGFyZW50KSB7XG4gICAgICAgICAgY29tcGxldGVkTWlsZXN0b25lQXNzZXNzbWVudENvdW50KytcbiAgICAgICAgICBjb25zb2xlLmxvZyhgRm91bmQgY29tcGxldGVkIE1JTEVTVE9ORSBhc3Nlc3NtZW50OiAke2tleX1gLCBpdGVtKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGBTa2lwcGluZyByb290LWxldmVsL3ByZS1lbnJvbGxtZW50IGFzc2Vzc21lbnQ6ICR7a2V5fWApXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zb2xlLmxvZyhgVG90YWwgY29tcGxldGVkIE1JTEVTVE9ORSBhc3Nlc3NtZW50czogJHtjb21wbGV0ZWRNaWxlc3RvbmVBc3Nlc3NtZW50Q291bnR9LCBSZXF1aXJlZDogJHtyZXF1aXJlZENvbXBsZXRlZEFzc2Vzc21lbnRzfWApXG5cbiAgICAvLyBJZiB3ZSBoYXZlIGVub3VnaCBjb21wbGV0ZWQgbWlsZXN0b25lIGFzc2Vzc21lbnRzLCB1bmxvY2sgdGhpcyBtaWxlc3RvbmVcbiAgICByZXR1cm4gY29tcGxldGVkTWlsZXN0b25lQXNzZXNzbWVudENvdW50ID49IHJlcXVpcmVkQ29tcGxldGVkQXNzZXNzbWVudHNcbiAgfVxuXG4gIHByaXZhdGUgZmluZENvbnRlbnRJbkhpZXJhcmNoeShjb250ZW50OiBhbnksIGlkZW50aWZpZXI6IHN0cmluZyk6IGFueSB7XG4gICAgaWYgKCFjb250ZW50KSByZXR1cm4gbnVsbFxuICAgIGlmIChjb250ZW50LmlkZW50aWZpZXIgPT09IGlkZW50aWZpZXIpIHJldHVybiBjb250ZW50XG4gICAgaWYgKGNvbnRlbnQuY2hpbGRyZW4pIHtcbiAgICAgIGZvciAoY29uc3QgY2hpbGQgb2YgY29udGVudC5jaGlsZHJlbikge1xuICAgICAgICBjb25zdCBmb3VuZCA9IHRoaXMuZmluZENvbnRlbnRJbkhpZXJhcmNoeShjaGlsZCwgaWRlbnRpZmllcilcbiAgICAgICAgaWYgKGZvdW5kKSByZXR1cm4gZm91bmRcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIGdldCBjb21wdXRlZFF1ZXJ5UGFyYW1zKCkge1xuICAgIGlmICh0aGlzLmlzQWxsb3dlZCAmJiAhdGhpcy5mb3JQcmV2aWV3ICYmIHRoaXMuaXNFbmFibGVkKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi50aGlzLnJlc291cmNlTGluay5xdWVyeVBhcmFtcyxcbiAgICAgICAgcHJlQXNzZXNzbWVudDogJ3RydWUnXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsXG4gIH1cblxuICBnZXQgaXNNaWxlc3RvbmUoKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMuX2NhY2hlSW5pdGlhbGl6ZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLl9jYWNoZWRJc01pbGVzdG9uZVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jb21wdXRlSXNNaWxlc3RvbmUoKVxuICB9XG5cbiAgZ2V0TWlsZXN0b25lQ29tcGxldGVkQ291bnQoKTogbnVtYmVyIHtcbiAgICBpZiAoIXRoaXMuY29udGVudCB8fCAhdGhpcy5oaWVyYXJjaHlNYXBEYXRhKSB7XG4gICAgICByZXR1cm4gMFxuICAgIH1cbiAgICBjb25zdCBtaWxlc3RvbmVEYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3RoaXMuY29udGVudC5pZGVudGlmaWVyXVxuICAgIGlmICghbWlsZXN0b25lRGF0YSB8fCAhbWlsZXN0b25lRGF0YS5sZWFmTm9kZXMpIHtcbiAgICAgIHJldHVybiAwXG4gICAgfVxuICAgIGxldCBjb21wbGV0ZWRDb3VudCA9IDBcbiAgICBtaWxlc3RvbmVEYXRhLmxlYWZOb2Rlcy5mb3JFYWNoKChsZWFmSWQ6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3QgbGVhZkRhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbbGVhZklkXVxuICAgICAgaWYgKGxlYWZEYXRhICYmIGxlYWZEYXRhLmNvbXBsZXRpb25TdGF0dXMgPT09IDIpIHtcbiAgICAgICAgY29tcGxldGVkQ291bnQrK1xuICAgICAgfVxuICAgIH0pXG4gICAgcmV0dXJuIGNvbXBsZXRlZENvdW50XG4gIH1cblxuICAvKipcbiAgICogR2V0IHVubG9jayBjcml0ZXJpYSBtZXNzYWdlIGZvciBsb2NrZWQgbWlsZXN0b25lc1xuICAgKi9cbiAgZ2V0TWlsZXN0b25lVW5sb2NrTWVzc2FnZSgpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5jb250ZW50IHx8ICF0aGlzLmhpZXJhcmNoeU1hcERhdGEpIHtcbiAgICAgIHJldHVybiAnJ1xuICAgIH1cblxuICAgIGNvbnN0IG1pbGVzdG9uZURhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbdGhpcy5jb250ZW50LmlkZW50aWZpZXJdXG4gICAgaWYgKCFtaWxlc3RvbmVEYXRhKSB7XG4gICAgICByZXR1cm4gJydcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiBoYXNobWFwIGhhcyBwcmUtY29tcHV0ZWQgdW5sb2NrIG1lc3NhZ2VcbiAgICBpZiAobWlsZXN0b25lRGF0YS51bmxvY2tNZXNzYWdlKSB7XG4gICAgICByZXR1cm4gbWlsZXN0b25lRGF0YS51bmxvY2tNZXNzYWdlXG4gICAgfVxuXG4gICAgY29uc3QgbWlsZXN0b25lSW5kZXggPSBtaWxlc3RvbmVEYXRhLm1pbGVzdG9uZUluZGV4XG5cbiAgICAvLyBNaWxlc3RvbmUgMSByZXF1aXJlcyBwcmUtYXNzZXNzbWVudCBjb21wbGV0aW9uXG4gICAgaWYgKG1pbGVzdG9uZUluZGV4ID09PSAwKSB7XG4gICAgICByZXR1cm4gJ0NvbXBsZXRlIHRoZSBwcmVsaW1pbmFyeSBhc3Nlc3NtZW50IHRvIHVubG9jayB0aGlzIG1pbGVzdG9uZSdcbiAgICB9XG5cbiAgICAvLyBPdGhlciBtaWxlc3RvbmVzIHJlcXVpcmUgcHJldmlvdXMgbWlsZXN0b25lIGNvbXBsZXRpb25cbiAgICByZXR1cm4gYENvbXBsZXRlIGFsbCBtYW5kYXRvcnkgY29udGVudCBhbmQgYXNzZXNzbWVudCBpbiBNaWxlc3RvbmUgJHttaWxlc3RvbmVJbmRleH0gdG8gdW5sb2NrIHRoaXMgbWlsZXN0b25lYFxuICB9XG5cbiAgLyoqXG4gICAqIEdldCBsb2NrIG1lc3NhZ2UgZm9yIGNvbnRlbnQgaW5zaWRlIGxvY2tlZCBtaWxlc3RvbmVzXG4gICAqL1xuICBnZXRQYXJlbnRNaWxlc3RvbmVMb2NrTWVzc2FnZSgpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5pc1BhcmVudE1pbGVzdG9uZUxvY2tlZCkge1xuICAgICAgcmV0dXJuICcnXG4gICAgfVxuICAgIHJldHVybiAnVGhpcyBjb250ZW50IGlzIGxvY2tlZC4gQ29tcGxldGUgcHJldmlvdXMgbWlsZXN0b25lIHRvIHZpZXcgdGhpcyBjb250ZW50LidcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgbG9jayBtZXNzYWdlIGZvciBtaWxlc3RvbmUgYXNzZXNzbWVudHNcbiAgICovXG4gIGdldEFzc2Vzc21lbnRMb2NrTWVzc2FnZSgpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5jb250ZW50IHx8ICF0aGlzLmhpZXJhcmNoeU1hcERhdGEpIHtcbiAgICAgIHJldHVybiAnJ1xuICAgIH1cblxuICAgIGNvbnN0IGhhc2hEYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3RoaXMuY29udGVudC5pZGVudGlmaWVyXVxuICAgIFxuICAgIC8vIENoZWNrIGlmIGhhc2htYXAgaGFzIHByZS1jb21wdXRlZCBhc3Nlc3NtZW50IGxvY2sgbWVzc2FnZVxuICAgIGlmIChoYXNoRGF0YSAmJiBoYXNoRGF0YS5hc3Nlc3NtZW50TG9ja01lc3NhZ2UpIHtcbiAgICAgIHJldHVybiBoYXNoRGF0YS5hc3Nlc3NtZW50TG9ja01lc3NhZ2VcbiAgICB9XG5cbiAgICBpZiAodGhpcy5pc01pbGVzdG9uZUFzc2Vzc21lbnRMb2NrZWQpIHtcbiAgICAgIHJldHVybiAnVGhpcyBjb250ZW50IGlzIGxvY2tlZC4gQ29tcGxldGUgYWxsIG1hbmRhdG9yeSBpdGVtcyB0byB1bmxvY2sgdGhlIGFzc2Vzc21lbnQuJ1xuICAgIH1cblxuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgc2hvdWxkU2hvd0Rvd25sb2FkQnV0dG9uKGNvbnRlbnQ6IE5zQ29udGVudC5JQ29udGVudCB8IG51bGwpOiBib29sZWFuIHtcbiAgICBpZiAoIWNvbnRlbnQpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIC8vIENoZWNrIGlmIGNvbnRlbnQgaGFzIGFuIGFydGlmYWN0IFVSTCAoZG93bmxvYWRhYmxlIHJlc291cmNlKVxuICAgIGlmICghY29udGVudC5hcnRpZmFjdFVybCkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgYmFzZSBjb250ZW50IHJlc291cmNlIGNhdGVnb3J5IGluY2x1ZGVzIFwiQ2FzZSBTdHVkeVwiXG4gICAgaWYgKCF0aGlzLmJhc2VDb250ZW50UmVhZERhdGE/LmNvdXJzZUNhdGVnb3J5IHx8XG4gICAgICB0aGlzLmJhc2VDb250ZW50UmVhZERhdGEuY291cnNlQ2F0ZWdvcnkgIT09IE5zQ29udGVudC5FQ291cnNlQ2F0ZWdvcnkuQ0FTRV9TVFVEWSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy9mb3IgcHVibGljIHNjZW5hcmlvIGNoZWNrIGlmIGl0cyBwbGF5ZXIgcGxhZ2UgdGhlbiBvbmx5IGVuYWJsZSBkb3dubG9hZFxuICAgIGlmICh0aGlzLmZvclByZXZpZXcgJiYgIXdpbmRvdy5sb2NhdGlvbi5ocmVmLmluY2x1ZGVzKCcvdmlld2VyLycpKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICAvLyBmb3IgbG9nZ2VkIGluIHVzZXIgY2hlY2sgaWYgdXNlciBlbnJvbGxlZCB0aGVuIG9ubHkgYWxsb3cgZG93bmxvYWRcbiAgICBpZiAoIXRoaXMuZm9yUHJldmlldyAmJiAhdGhpcy5pc0Vucm9sbGVkKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICAvLyBEZWZpbmUgZG93bmxvYWRhYmxlIE1JTUUgdHlwZXNcbiAgICBjb25zdCBkb3dubG9hZGFibGVNaW1lVHlwZXMgPSBbXG4gICAgICBOc0NvbnRlbnQuRU1pbWVUeXBlcy5QREZcbiAgICBdXG5cbiAgICByZXR1cm4gZG93bmxvYWRhYmxlTWltZVR5cGVzLmluY2x1ZGVzKGNvbnRlbnQubWltZVR5cGUpXG4gIH1cblxuICBkb3dubG9hZENvbnRlbnQoY29udGVudDogTnNDb250ZW50LklDb250ZW50LCBldmVudD86IE1vdXNlRXZlbnQpIHtcbiAgICBpZiAoZXZlbnQpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KClcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXG4gICAgfVxuICAgIGNvbnN0IHBhZ2VJZCA9IGBhcHAvdG9jL3BhZ2VJZC8ke2NvbnRlbnQuaWRlbnRpZmllcn1gXG4gICAgdGhpcy5yZXNvdXJjZURvd25sb2FkSGVscGVyU3ZjLmRvd25sb2FkUERGKGNvbnRlbnQsIHBhZ2VJZClcbiAgICBjb25zb2xlLmxvZygnY29udGVudCcsIGNvbnRlbnQpXG4gICAgY29uc29sZS5sb2coJ2Jhc2VDb250ZW50JywgdGhpcy5iYXNlQ29udGVudFJlYWREYXRhKVxuICB9XG5cblxuXG4gIC8qKlxuICAgKiBWaWV3IG1pbGVzdG9uZSBhY2hpZXZlbWVudCAtIGNhbGxzIHRoZSBhY2hpZXZlbWVudCBBUEkgYW5kIHNob3dzIHRoZSByZXN1bHRcbiAgICovXG4gIHZpZXdNaWxlc3RvbmVBY2hpZXZlbWVudChldmVudD86IE1vdXNlRXZlbnQpIHtcbiAgICBpZiAoZXZlbnQpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KClcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLmNvbnRlbnQgfHwgIXRoaXMuYmF0Y2hJZCB8fCB0aGlzLmFjaGlldmVtZW50TG9hZGluZykge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gR2V0IHVzZXIgSUQgZnJvbSBDb25maWd1cmF0aW9uc1NlcnZpY2VcbiAgICBjb25zdCB1c2VySWQgPSB0aGlzLmNvbmZpZ1N2Yz8udXNlclByb2ZpbGU/LnVzZXJJZFxuICAgIGlmICghdXNlcklkKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdVc2VyIElEIG5vdCBmb3VuZCcpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBFeHRyYWN0IG1pbGVzdG9uZSBJRCAoZS5nLiwgXCJtMVwiLCBcIm0yXCIpIGZyb20gdGhlIGNvbnRlbnQgbmFtZSBvciBpbmRleFxuICAgIC8vIFRyeSB0byBnZXQgbWlsZXN0b25lIG51bWJlciBmcm9tIHRoZSBpbmRleCBvciBleHRyYWN0IGZyb20gY29udGVudFxuICAgIGxldCBtaWxlc3RvbmVJZCA9ICdtJyArICh0aGlzLmluZGV4IC0gMSkgLy8gaW5kZXggaXMgdHlwaWNhbGx5IDEtYmFzZWQsIG1pbGVzdG9uZXMgYXJlIDAtYmFzZWRcblxuICAgIC8vIElmIGNvbnRlbnQgbmFtZSBjb250YWlucyBtaWxlc3RvbmUgbnVtYmVyLCBleHRyYWN0IGl0XG4gICAgaWYgKHRoaXMuY29udGVudC5uYW1lKSB7XG4gICAgICBjb25zdCBtYXRjaCA9IHRoaXMuY29udGVudC5uYW1lLm1hdGNoKC9taWxlc3RvbmVcXHMqKFxcZCspL2kpXG4gICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgbWlsZXN0b25lSWQgPSAnbScgKyBtYXRjaFsxXVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGNvdXJzZUlkID0gdGhpcy5iYXNlQ29udGVudFJlYWREYXRhPy5pZGVudGlmaWVyIHx8IHRoaXMucm9vdElkXG5cbiAgICB0aGlzLmFjaGlldmVtZW50TG9hZGluZyA9IHRydWVcblxuICAgIHRoaXMuYXBwVG9jU3ZjLmdlbmVyYXRlTWlsZXN0b25lQWNoaWV2ZW1lbnQodXNlcklkLCBjb3Vyc2VJZCwgdGhpcy5iYXRjaElkLCBtaWxlc3RvbmVJZCkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChyZXNwb25zZTogYW55KSA9PiB7XG4gICAgICAgIHRoaXMuYWNoaWV2ZW1lbnRMb2FkaW5nID0gZmFsc2VcbiAgICAgICAgY29uc29sZS5sb2coJ0FjaGlldmVtZW50IGdlbmVyYXRlZCBzdWNjZXNzZnVsbHk6JywgcmVzcG9uc2UpXG4gICAgICAgIC8vIFNob3cgYWNoaWV2ZW1lbnQgZGlhbG9nIG9yIGhhbmRsZSByZXNwb25zZVxuICAgICAgICBpZiAocmVzcG9uc2UgJiYgcmVzcG9uc2UucmVzdWx0KSB7XG4gICAgICAgICAgLy8gT3BlbiBhIGRpYWxvZyB0byBzaG93IHRoZSBhY2hpZXZlbWVudFxuICAgICAgICAgIHRoaXMuZGlhbG9nLm9wZW4oQ2VydGlmaWNhdGVEaWFsb2dDb21wb25lbnQsIHtcbiAgICAgICAgICAgIHdpZHRoOiAnMTMwMHB4JyxcbiAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgY2V0OiByZXNwb25zZS5yZXN1bHQucHJpbnRVcmkgfHwgcmVzcG9uc2UucmVzdWx0LnN2Z0RhdGEsXG4gICAgICAgICAgICAgIGNlcnRJZDogcmVzcG9uc2UucmVzdWx0LmlkZW50aWZpZXIsXG4gICAgICAgICAgICAgIGlzQWNoaWV2ZW1lbnQ6IHRydWVcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGVycm9yOiAoZXJyb3I6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLmFjaGlldmVtZW50TG9hZGluZyA9IGZhbHNlXG4gICAgICAgIC8vIFNob3cgZXJyb3IgbWVzc2FnZSBpbiBzbmFja2JhclxuICAgICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBlcnJvcj8uZXJyb3I/LnJlc3VsdD8ubWVzc2FnZSB8fCBlcnJvcj8ubWVzc2FnZSB8fCAnRmFpbGVkIHRvIGdlbmVyYXRlIGFjaGlldmVtZW50J1xuICAgICAgICB0aGlzLnNuYWNrQmFyLm9wZW4oZXJyb3JNZXNzYWdlLCAnQ2xvc2UnLCB7XG4gICAgICAgICAgZHVyYXRpb246IDUwMDAsXG4gICAgICAgICAgaG9yaXpvbnRhbFBvc2l0aW9uOiAnY2VudGVyJyxcbiAgICAgICAgICB2ZXJ0aWNhbFBvc2l0aW9uOiAnYm90dG9tJyxcbiAgICAgICAgICBwYW5lbENsYXNzOiBbJ2Vycm9yLXNuYWNrYmFyJ11cbiAgICAgICAgfSlcbiAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgZ2VuZXJhdGluZyBhY2hpZXZlbWVudDonLCBlcnJvcilcbiAgICAgIH1cbiAgICB9KVxuICB9XG4gLyoqXG4gICAqIENoZWNrIGlmIHRleHQgaXMgdHJ1bmNhdGVkIChoYXMgZWxsaXBzaXMpIC0gZm9yIHNpbmdsZSBsaW5lIHRleHRcbiAgICogQHBhcmFtIGVsZW1lbnQgVGhlIEhUTUxFbGVtZW50IHRvIGNoZWNrXG4gICAqIEByZXR1cm5zIHRydWUgaWYgdGV4dCBpcyB0cnVuY2F0ZWQsIGZhbHNlIG90aGVyd2lzZVxuICAgKi9cbiAgaXNUZXh0VHJ1bmNhdGVkKGVsZW1lbnQ6IEhUTUxFbGVtZW50KTogYm9vbGVhbiB7XG4gICAgaWYgKCFlbGVtZW50KSByZXR1cm4gZmFsc2VcbiAgICByZXR1cm4gZWxlbWVudC5vZmZzZXRXaWR0aCA8IGVsZW1lbnQuc2Nyb2xsV2lkdGhcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0gZWxlbWVudCBUaGUgSFRNTEVsZW1lbnQgdG8gY2hlY2tcbiAgICogQHJldHVybnMgdHJ1ZSBpZiB0ZXh0IGlzIHRydW5jYXRlZCwgZmFsc2Ugb3RoZXJ3aXNlXG4gICAqL1xuICBpc011bHRpTGluZVRydW5jYXRlZChlbGVtZW50OiBIVE1MRWxlbWVudCk6IGJvb2xlYW4ge1xuICAgIGlmICghZWxlbWVudCkgcmV0dXJuIGZhbHNlXG4gICAgcmV0dXJuIGVsZW1lbnQuc2Nyb2xsSGVpZ2h0ID4gZWxlbWVudC5jbGllbnRIZWlnaHRcbiAgfVxufVxuIiwiPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnQgJiYgIWlzUHJlQXNzZXNzbWVudFwiPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc0NvbGxlY3Rpb24gJiYgIWlzTW9kdWxlXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwiY29sbGVjdGlvblRlbXBsYXRlXCI+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvbmctY29udGFpbmVyPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc0NvbGxlY3Rpb24gJiYgaXNNb2R1bGVcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnQ/Lm1vZHVsZVJlc291cnNlQ291bnRcIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwiY29sbGVjdGlvblRlbXBsYXRlXCI+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8ZGl2ICpuZ0lmPVwiaXNSZXNvdXJjZVwiIGNsYXNzPVwicmVzb3VyY2UtY29udGFpbmVyXCJcbiAgICAgICAgW25nQ2xhc3NdPVwicGF0aFNldD8uaGFzKGNvbnRlbnQ/LmlkZW50aWZpZXIpICYmIGlzRW5yb2xsZWQgPyAnY29udGVudC1hY3RpdmUtcmVzb3VyY2UnOiAnY29udGVudC1ub3QtYWN0aXZlLXJlc291cmNlJ1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwicmVzb3VyY2UgZmxleCAgc206ZmxleC1yb3cgZmxleC1zdGFydCB3aWR0aC1leHBhbmQgdy0xMDAgc206cHItNCBzbTp3LWF1dG9cIlxuICAgICAgICAgICAgW25nQ2xhc3NdPVwieydhY3RpdmVSZXNvdXJjZSc6IHBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKSAmJiBpc0Vucm9sbGVkfVwiPlxuICAgICAgICAgICAgPCEtLSBMb2NrIG1lc3NhZ2UgZm9yIGN1cmF0ZWQgcHJvZ3JhbXMgb25seSAoc2hvd24gYWJvdmUgY29udGVudCkgLS0+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudD8ucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCAmJiBjaGVja0ZvckN1cmF0ZWRQcm9ncmFtICYmXG4gICAgICAgICAgICAhaXNDb250ZW50VW5sb2NrZWRcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29udGVudC1sb2NraW5nIGZsZXggdy1mdWxsIGZsZXgtbWlkZGxlIG1iLTIgZ2FwLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwibG9jay1pY29uXCI+bG9jazwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibG9jay1tZXNzYWdlIG1hdC1ib2R5LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIFRoZSBjb250ZW50IGlzIGxvY2tlZC4gQ29tcGxldGUgcHJvZ3JhbSBvciBhbGwgY291cnNlcyB0byB2aWV3IHRoaXMgbW9kdWxlXG4gICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnQ/LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgJiYgY2hlY2tGb3JDdXJhdGVkUHJvZ3JhbSAmJlxuICAgICAgICAgICAgaXNDb250ZW50VW5sb2NrZWRcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29udGVudC1sb2NraW5nIGZsZXggdy1mdWxsIGZsZXgtbWlkZGxlIG1iLTIgZ2FwLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwidW5sb2NrLWljb25cIj5sb2NrX29wZW5fcmlnaHQ8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInVubG9jay1tZXNzYWdlIG1hdC1ib2R5LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMgY29udGVudCBpcyB1bmxvY2tlZC5cbiAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXdyYXAgaXRlbXMtc3RhcnQganVzdGlmeS1zdGFydCBzbTpqdXN0aWZ5LWVuZFwiPlxuICAgICAgICAgICAgICAgIDwhLS0gPGJ1dHRvbiAqbmdJZj1cIiFmb3JQcmV2aWV3ICYmIGNvbnRlbnQ/LmFydGlmYWN0VXJsICYmICFpc1hTbWFsbCAmJiBpc0FsbG93ZWQgJiYgaXNFbmFibGVkXCIgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgIG1hdC1pY29uLWJ1dHRvbiBjbGFzcz1cIlwiIFttYXRNZW51VHJpZ2dlckZvcl09XCJidXR0b25NZW51XCI+XG4gICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5tb3JlX3ZlcnRpY2FsPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj4gLS0+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzRW5yb2xsZWQgICYmICFpc01pbGVzdG9uZUxvY2tlZCAmJiAhaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWRcIj5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCIhZm9yUHJldmlldyAmJiAgY29udGVudD8uaWRlbnRpZmllciAmJiBnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKSA7IGVsc2UgZWxzZUJsb2NrXCI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRDb21wbGV0aW9uU3RhdHVzKGNvbnRlbnQ/LmlkZW50aWZpZXIpID09IDJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29tcGxldGVkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJjb21wbGV0ZWQtaWNvblwiIFtjb2xvcl09XCJibHVlXCI+Y2hlY2tfY2lyY2xlPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRDb21wbGV0aW9uU3RhdHVzKGNvbnRlbnQ/LmlkZW50aWZpZXIpIDwgMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxjaXJjbGUtcHJvZ3Jlc3MgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBwcm9ncmVzc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwZXJjZW50XT1cImdldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpXCIgW3JhZGl1c109XCIxMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZVdpZHRoXT1cIjJcIiBbaW5uZXJTdHJva2VXaWR0aF09XCIyXCIgW3NwYWNlXT1cIi0yXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlQ29sb3JdPVwicHJvZ3Jlc3NDb2xvcjIoKVwiIFtpbm5lclN0cm9rZUNvbG9yXT1cIidyZ2JhKDAsIDAsIDAsIDAuMTYpJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthbmltYXRpb25dPVwidHJ1ZVwiIFthbmltYXRpb25EdXJhdGlvbl09XCIyNTBcIiBbc2hvd1RpdGxlXT1cImZhbHNlXCIgW3Nob3dVbml0c109XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93U3VidGl0bGVdPVwiZmFsc2VcIiBbc2hvd0lubmVyU3Ryb2tlXT1cInRydWVcIiBbY2xvY2t3aXNlXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYmFja2dyb3VuZE9wYWNpdHldPVwiMFwiIFtiYWNrZ3JvdW5kR3JhZGllbnRdPVwiZmFsc2VcIiBbYmFja2dyb3VuZFN0cm9rZVdpZHRoXT1cIjNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRUb29sdGlwPVwiSW4gcHJvZ3Jlc3NcIiBbc2hvd1plcm9PdXRlclN0cm9rZV09ZmFsc2UgW2JhY2tncm91bmRQYWRkaW5nXT1cIi05XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0YXJ0RnJvbVplcm9dPVwiZmFsc2VcIiBbYmFja2dyb3VuZFBhZGRpbmddPVwiMFwiIFtpbWFnZUhlaWdodF09XCIyMlwiIFtpbWFnZVdpZHRoXT1cIjIyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dCYWNrZ3JvdW5kXT1cImZhbHNlXCIgW291dGVyU3Ryb2tlTGluZWNhcF09XCInYnV0dCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2NpcmNsZS1wcm9ncmVzcz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIDx3cy13aWRnZXQtY29udGVudC1wcm9ncmVzcyAqbmdJZj1cImNvbnRlbnQ/LmlkZW50aWZpZXJcIiBbZm9yUHJldmlld109XCJmb3JQcmV2aWV3XCJcbiAgICAgICAgICAgICAgICAgICAgW2NvbnRlbnRJZF09XCJjb250ZW50Py5pZGVudGlmaWVyXCIgY2xhc3M9XCJwcm9ncmVzcy1iYXItdGhpblwiIFtwcm9ncmVzc109XCJjb250ZW50Py5jb21wbGV0aW9uUGVyY2VudGFnZVwiXG4gICAgICAgICAgICAgICAgICAgIFtwcm9ncmVzc1R5cGVdPVwiJ3BlcmNlbnRhZ2UnXCI+XG4gICAgICAgICAgICAgICAgICA8L3dzLXdpZGdldC1jb250ZW50LXByb2dyZXNzPiAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNlbHNlQmxvY2s+XG4gICAgICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlLXByb2dyZXNzIGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgcHJvZ3Jlc3NcIiBbcGVyY2VudF09XCIwXCIgW3JhZGl1c109XCIxMVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlV2lkdGhdPVwiMlwiIFtpbm5lclN0cm9rZVdpZHRoXT1cIjJcIiBbb3V0ZXJTdHJva2VDb2xvcl09XCInIzgwODA4MCdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpbm5lclN0cm9rZUNvbG9yXT1cIicjODA4MDgwJ1wiIFthbmltYXRpb25dPVwidHJ1ZVwiIFtzcGFjZV09XCItMlwiIFtzaG93VW5pdHNdPVwiZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthbmltYXRpb25EdXJhdGlvbl09XCIyNTBcIiBbc2hvd1RpdGxlXT1cImZhbHNlXCIgW2JhY2tncm91bmRQYWRkaW5nXT1cIjBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtiYWNrZ3JvdW5kUGFkZGluZ109XCItOVwiIFtvdXRlclN0cm9rZUxpbmVjYXBdPVwiJ2J1dHQnXCIgbWF0VG9vbHRpcD1cIk5vdCBzdGFydGVkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2hvd1N1YnRpdGxlXT1cImZhbHNlXCIgW3Nob3dJbm5lclN0cm9rZV09XCJ0cnVlXCIgW2Nsb2Nrd2lzZV09XCJ0cnVlXCIgW2ltYWdlSGVpZ2h0XT1cIjIyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaW1hZ2VXaWR0aF09XCIyMlwiIFtzaG93QmFja2dyb3VuZF09XCJmYWxzZVwiPjwvY2lyY2xlLXByb2dyZXNzPlxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSA8cD5ubyBkYXRhPC9wPiAtLT5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPCEtLSBkZWFjdGl2YXRlZCBhcyBwZXIgTklDIENFTyByZXF1aXJlbWVudCB0byBhY2Nlc3MgY291cnNlIHd0aG91dCBsb2dpbiAtLT5cbiAgICAgICAgICAgIDwhLS0gRm9yIGxvY2tlZCBhc3Nlc3NtZW50czogc2hvdyBjb250ZW50IGJ1dCBtYWtlIGl0IG5vbi1jbGlja2FibGUgLS0+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwid2lkdGgtZXhwYW5kXCIgKm5nSWY9XCJpc01pbGVzdG9uZUFzc2Vzc21lbnRMb2NrZWQgJiYgaXNFbnJvbGxlZDsgZWxzZSBjbGlja2FibGVDb250ZW50XCJcbiAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J21sLTMnOiBpc0Vucm9sbGVkfVwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXRydW5jYXRlIG9wYWNpdHktNjBcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2wgc206ZmxleC1yb3cgZmxleC13cmFwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgZ2FwLTIgdy1mdWxsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwidGV4dC1ncmF5LTUwMFwiPmxvY2s8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwibWFyZ2luLXJlbW92ZSB0ZXh0LXRydW5jYXRlIG1hdC1ib2R5LTIgZmxleC1hdXRvIGZvbnQtYm9sZCBub2R0cmFuc2xhdGUgdGV4dC1ncmF5LTYwMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttYXRUb29sdGlwXT1cIihjb250ZW50Py5uYW1lICsgKGNvbnRlbnQ/LmNvbnRleHRDYXRlZ29yeSAmJiAoY29udGVudD8ucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCkgPyAnIC0gJyArIGNvbnRlbnQ/LmNvbnRleHRDYXRlZ29yeSA6ICcnKSkubGVuZ3RoID4gNTAgPyAoY29udGVudD8ubmFtZSArIChjb250ZW50Py5jb250ZXh0Q2F0ZWdvcnkgJiYgKGNvbnRlbnQ/LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQpID8gJyAtICcgKyBjb250ZW50Py5jb250ZXh0Q2F0ZWdvcnkgOiAnJykpIDogJydcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRUb29sdGlwUG9zaXRpb249XCJhYm92ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyAoY29udGVudD8ubmFtZSArIChjb250ZW50Py5jb250ZXh0Q2F0ZWdvcnkgJiYgKGNvbnRlbnQ/LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgKT8gJyAtICcgKyBjb250ZW50Py5jb250ZXh0Q2F0ZWdvcnkgOiAnJykpIHwgdHJ1bmNhdGU6NTAgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY29udGVudC10eXBlIG9wdGlvbmFsLXNwYW4gbm9kdHJhbnNsYXRlXCIgKm5nSWY9XCJjb250ZW50Py5vcHRpb25hbFJlYWRpbmdcIj57e1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwbGF5ZXJicmllZi5vcHRpb25hbCcgfCB0cmFuc2xhdGUgfCB0aXRsZWNhc2V9fSA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8IS0tIGZvciBkZWZhdWx0IGdyZXkgaWNvbnMgLS0+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhcGF0aFNldD8uaGFzKGNvbnRlbnQ/LmlkZW50aWZpZXIpIHx8ICFpc0Vucm9sbGVkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVzaWNvbnMgd3MtbWF0LWJsYWNrNjAtdGV4dFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvdmlkZW8uc3ZnXCIgYWx0PVwiVmlkZW9cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCIgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ3ZpZGVvL21wNCcgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICd2aWRlby94LXlvdXR1YmUnIHx8XG4gICAgICAgICAgICAgICAgICAgICAgY29udGVudD8ubWltZVR5cGUgPT09J2FwcGxpY2F0aW9uL3gtbXBlZ1VSTCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2F1ZGlvLnN2Z1wiIGFsdD1cIkF1ZGlvXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhdWRpby9tcGVnJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvcGRmLnN2Z1wiIGFsdD1cIlBERlwiIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vcGRmJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvbGluay5zdmdcIiBhbHQ9XCJJbnRlcmFjdGl2ZUNvbnRlbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5la3N0ZXAuaHRtbC1hcmNoaXZlJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ3RleHQveC11cmwnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9hc3Nlc3NtZW50LnN2Z1wiIGFsdD1cIkFzc2Vzc21lbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL2pzb24nIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vcXVpeicgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi92bmQuc3VuYmlyZC5xdWVzdGlvbnNldCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2ltYWdlLnN2Z1wiIGFsdD1cIkltYWdlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdpbWFnZS9wbmcnIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnaW1hZ2UvanBlZydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2NvbnRlbnRfY29weS5zdmdcIiBjbGFzcz1cImNvbnRlbnRpY29uXCIgYWx0PVwiQ291cnNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLmVrc3RlcC5jb250ZW50LWNvbGxlY3Rpb24nIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vc3VydmV5J1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvbW9kdWxlLnN2Z1wiIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbHQ9XCJvZmZsaW5lIHNlc3Npb25zXCIgKm5nSWY9XCJjb250ZW50Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vb2ZmbGluZSdcIj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkNPTVBfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuU1RBTkRBTE9ORV9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5QUkFDVElDRV9SRVNPVVJDRVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInJlc291cmNlRHVyYXRpb24gd3MtbWF0LWJsYWNrNjAtdGV4dCBub2R0cmFuc2xhdGVcIj57eyBjb250ZW50Py5tYXhRdWVzdGlvbnNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH19IHt7ICdwbGF5ZXJicmllZi5xdWVzdGlvbnMnIHwgdHJhbnNsYXRlIHwgdGl0bGVjYXNlfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiEoY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5GSU5BTF9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5DT01QX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlNUQU5EQUxPTkVfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuUFJBQ1RJQ0VfUkVTT1VSQ0UpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicmVzb3VyY2VEdXJhdGlvbiB3cy1tYXQtYmxhY2s2MC10ZXh0IG5vZHRyYW5zbGF0ZVwiPnt7IChjb250ZW50Py5kdXJhdGlvbnx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWVyYXJjaHlNYXBEYXRhW2NvbnRlbnQ/LmlkZW50aWZpZXJdPy5leHBlY3RlZER1cmF0aW9uIHx8IDApfFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGlwZUR1cmF0aW9uVHJhbnNmb3JtOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2htcydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIDwhLS0gTG9jayBtZXNzYWdlIGRpc3BsYXllZCBCRUxPVyBhc3Nlc3NtZW50IGRldGFpbHMgd2hlbiBsb2NrZWQgLS0+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbnRlbnQtbG9ja2luZyBmbGV4IHctZnVsbCBmbGV4LW1pZGRsZSBtdC0yIGdhcC0yIHB4LTIgcHktMSBiZy1vcmFuZ2UtNTAgYm9yZGVyLWwtNCBib3JkZXItb3JhbmdlLTQwMFwiPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJsb2NrLWljb24gdGV4dC1vcmFuZ2UtNjAwXCIgc3R5bGU9XCJmb250LXNpemU6IDE4cHg7IHdpZHRoOiAxOHB4OyBoZWlnaHQ6IDE4cHg7XCI+bG9jazwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibG9jay1tZXNzYWdlIG1hdC1ib2R5LTIgdGV4dC1vcmFuZ2UtODAwXCIgc3R5bGU9XCJmb250LXNpemU6IDEzcHg7XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBUaGlzIGNvbnRlbnQgaXMgbG9ja2VkLiBDb21wbGV0ZSBhbGwgbWFuZGF0b3J5IGl0ZW1zIHRvIHVubG9jayB0aGUgYXNzZXNzbWVudC5cbiAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIDwhLS0gQ2xpY2thYmxlIGNvbnRlbnQgdGVtcGxhdGUgKHdoZW4gTk9UIGxvY2tlZCkgLS0+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgI2NsaWNrYWJsZUNvbnRlbnQ+XG4gICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJ3aWR0aC1leHBhbmRcIlxuICAgICAgICAgICAgICAgICAgICBbY2xhc3MuZGlzYWJsZWRdPVwiKGZvclByZXZpZXcgfHwgIWlzRW5hYmxlZCB8fCAhaXNFbnJvbGxlZCB8fCAhaXNCYXRjaEluUHJvZ2VzcyB8fCAhaXNDb250ZW50VW5sb2NrZWQgfHwgaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQpID8gdHJ1ZSA6IG51bGxcIlxuICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J21sLTMnOiBpc0Vucm9sbGVkfVwiXG4gICAgICAgICAgICAgICAgICAgIFtyb3V0ZXJMaW5rXT1cIihpc0FsbG93ZWQgJiYgIWZvclByZXZpZXcgJiYgaXNFbmFibGVkICYmICFpc1BhcmVudE1pbGVzdG9uZUxvY2tlZCkgPyByZXNvdXJjZUxpbmsudXJsIDogbnVsbFwiXG4gICAgICAgICAgICAgICAgICAgIFtxdWVyeVBhcmFtc109XCIoaXNBbGxvd2VkICYmICFmb3JQcmV2aWV3ICYmIGlzRW5hYmxlZCAmJiAhaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQpICA/IHJlc291cmNlTGluay5xdWVyeVBhcmFtcyA6IG51bGxcIlxuICAgICAgICAgICAgICAgICAgICBbbWF0VG9vbHRpcF09XCJpc1BhcmVudE1pbGVzdG9uZUxvY2tlZCA/ICdUaGlzIGNvbnRlbnQgaXMgbG9ja2VkLiBDb21wbGV0ZSBwcmV2aW91cyBtaWxlc3RvbmUgdG8gdmlldyB0aGlzIGNvbnRlbnQuJyA6ICcnXCJcbiAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcFBvc2l0aW9uPVwiYWJvdmVcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBbbmdDbGFzc109XCJ7J3Jlc291cmNlLWFjdGl2ZSc6IHBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKSAmJiBpc0Vucm9sbGVkfVwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC10cnVuY2F0ZSBcIiBbbmdDbGFzc109XCJ7J2N1cnNvci1wb2ludGVyJzogIWlzRW5hYmxlZCAmJiBpc0Vucm9sbGVkfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiY29udGVudC52aWV3Q2hpbGRyZW4gPSAhY29udGVudC52aWV3Q2hpbGRyZW47IHJhaXNlVGVsZW1ldHJ5KCk7IGNoYW5nZVJlc291cmNlKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sIHNtOmZsZXgtcm93IGZsZXgtd3JhcFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwibWFyZ2luLXJlbW92ZSB0ZXh0LXRydW5jYXRlIG1hdC1ib2R5LTIgZmxleC1hdXRvIGZvbnQtYm9sZCBub2R0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J3RleHQtYWN0aXZlJzogcGF0aFNldD8uaGFzKGNvbnRlbnQ/LmlkZW50aWZpZXIpICYmIGlzRW5yb2xsZWR9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21hdFRvb2x0aXBdPVwiKGNvbnRlbnQ/Lm5hbWUgKyAoY29udGVudD8uY29udGV4dENhdGVnb3J5ICYmIChjb250ZW50Py5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5GSU5BTF9BU1NFU1NNRU5UKSA/ICcgLSAnICsgY29udGVudD8uY29udGV4dENhdGVnb3J5IDogJycpKS5sZW5ndGggPiA1MCA/IChjb250ZW50Py5uYW1lICsgKGNvbnRlbnQ/LmNvbnRleHRDYXRlZ29yeSAmJiAoY29udGVudD8ucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCkgPyAnIC0gJyArIGNvbnRlbnQ/LmNvbnRleHRDYXRlZ29yeSA6ICcnKSkgOiAnJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXBQb3NpdGlvbj1cImFib3ZlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IChjb250ZW50Py5uYW1lICsgKGNvbnRlbnQ/LmNvbnRleHRDYXRlZ29yeSAmJiAoY29udGVudD8ucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCk/ICcgLSAnICsgY29udGVudD8uY29udGV4dENhdGVnb3J5IDogJycpKSB8IHRydW5jYXRlOjUwIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY29udGVudC10eXBlIG9wdGlvbmFsLXNwYW4gbm9kdHJhbnNsYXRlXCIgKm5nSWY9XCJjb250ZW50Py5vcHRpb25hbFJlYWRpbmdcIj57e1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAncGxheWVyYnJpZWYub3B0aW9uYWwnIHwgdHJhbnNsYXRlIHwgdGl0bGVjYXNlfX0gPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIGZvciBkZWZhdWx0IGdyZXkgaWNvbnMgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIXBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKSB8fCAhaXNFbnJvbGxlZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZXNpY29ucyB3cy1tYXQtYmxhY2s2MC10ZXh0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvdmlkZW8uc3ZnXCIgYWx0PVwiVmlkZW9cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICd2aWRlby9tcDQnIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAndmlkZW8veC15b3V0dWJlJyB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50Py5taW1lVHlwZSA9PT0nYXBwbGljYXRpb24veC1tcGVnVVJMJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2F1ZGlvLnN2Z1wiIGFsdD1cIkF1ZGlvXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIiAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXVkaW8vbXBlZydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9wZGYuc3ZnXCIgYWx0PVwiUERGXCIgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vcGRmJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2xpbmsuc3ZnXCIgYWx0PVwiSW50ZXJhY3RpdmVDb250ZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5la3N0ZXAuaHRtbC1hcmNoaXZlJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ3RleHQveC11cmwnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvYXNzZXNzbWVudC5zdmdcIiBhbHQ9XCJBc3Nlc3NtZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL2pzb24nIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vcXVpeicgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi92bmQuc3VuYmlyZC5xdWVzdGlvbnNldCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9pbWFnZS5zdmdcIiBhbHQ9XCJJbWFnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdpbWFnZS9wbmcnIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnaW1hZ2UvanBlZydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9jb250ZW50X2NvcHkuc3ZnXCIgY2xhc3M9XCJjb250ZW50aWNvblwiIGFsdD1cIkNvdXJzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi92bmQuZWtzdGVwLmNvbnRlbnQtY29sbGVjdGlvbicgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9zdXJ2ZXknXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvbW9kdWxlLnN2Z1wiIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWx0PVwib2ZmbGluZSBzZXNzaW9uc1wiICpuZ0lmPVwiY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL29mZmxpbmUnXCI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkNPTVBfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlNUQU5EQUxPTkVfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInJlc291cmNlRHVyYXRpb24gd3MtbWF0LWJsYWNrNjAtdGV4dCBub2R0cmFuc2xhdGVcIj57eyBjb250ZW50Py5tYXhRdWVzdGlvbnNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9fSB7eyAncGxheWVyYnJpZWYucXVlc3Rpb25zJyB8IHRyYW5zbGF0ZSB8IHRpdGxlY2FzZX19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiEoY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5GSU5BTF9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuQ09NUF9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuU1RBTkRBTE9ORV9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuUFJBQ1RJQ0VfUkVTT1VSQ0UpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInJlc291cmNlRHVyYXRpb24gd3MtbWF0LWJsYWNrNjAtdGV4dCBub2R0cmFuc2xhdGVcIj57eyAoY29udGVudD8uZHVyYXRpb258fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZXJhcmNoeU1hcERhdGFbY29udGVudD8uaWRlbnRpZmllcl0/LmV4cGVjdGVkRHVyYXRpb24gfHwgMCl8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGlwZUR1cmF0aW9uVHJhbnNmb3JtOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdobXMnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBmb3Igd2hpdGUgaWNvbnMgd2hlbiBjb250ZW50IGhpZ2hsaWdodGVkIC0tPlxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwicGF0aFNldD8uaGFzKGNvbnRlbnQ/LmlkZW50aWZpZXIpICYmIGlzRW5yb2xsZWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZXNpY29ucyB3cy1tYXQtd2hpdGUtdGV4dFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L3doaXRlL3ZpZGVvLnN2Z1wiIGFsdD1cIlZpZGVvXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICd2aWRlby9tcDQnIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAndmlkZW8veC15b3V0dWJlJyB8fFxuICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ/Lm1pbWVUeXBlID09PSdhcHBsaWNhdGlvbi94LW1wZWdVUkwnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvd2hpdGUvYXVkaW8uc3ZnXCIgYWx0PVwiQXVkaW9cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCIgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2F1ZGlvL21wZWcnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvd2hpdGUvcGRmLnN2Z1wiIGFsdD1cIlBERlwiIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vcGRmJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L3doaXRlL2xpbmsuc3ZnXCIgYWx0PVwiSW50ZXJhY3RpdmVDb250ZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi92bmQuZWtzdGVwLmh0bWwtYXJjaGl2ZScgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICd0ZXh0L3gtdXJsJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L3doaXRlL2Fzc2Vzc21lbnQuc3ZnXCIgYWx0PVwiQXNzZXNzbWVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vanNvbicgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9xdWl6JyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5zdW5iaXJkLnF1ZXN0aW9uc2V0J1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvaW1hZ2Uuc3ZnXCIgYWx0PVwiSW1hZ2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2ltYWdlL3BuZycgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICdpbWFnZS9qcGVnJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L3doaXRlL2NvbnRlbnRfY29weS5zdmdcIiBjbGFzcz1cImNvbnRlbnRpY29uXCIgYWx0PVwiQ291cnNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLmVrc3RlcC5jb250ZW50LWNvbGxlY3Rpb24nIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vc3VydmV5J1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L3doaXRlL21vZHVsZS5zdmdcIiBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWx0PVwib2ZmbGluZSBzZXNzaW9uc1wiICpuZ0lmPVwiY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL29mZmxpbmUnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuQ09NUF9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5TVEFOREFMT05FX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicmVzb3VyY2VEdXJhdGlvbiB3cy1tYXQtYmxhY2s2MC10ZXh0IG5vZHRyYW5zbGF0ZVwiPnt7IGNvbnRlbnQ/Lm1heFF1ZXN0aW9uc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfX0ge3sgJ3BsYXllcmJyaWVmLnF1ZXN0aW9ucycgfCB0cmFuc2xhdGUgfCB0aXRsZWNhc2V9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIShjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkNPTVBfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuU1RBTkRBTE9ORV9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5QUkFDVElDRV9SRVNPVVJDRSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJyZXNvdXJjZUR1cmF0aW9uIHdzLW1hdC1ibGFjazYwLXRleHQgbm9kdHJhbnNsYXRlXCI+e3sgKGNvbnRlbnQ/LmR1cmF0aW9ufHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZXJhcmNoeU1hcERhdGFbY29udGVudD8uaWRlbnRpZmllcl0/LmV4cGVjdGVkRHVyYXRpb24gfHwgMCl8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXBlRHVyYXRpb25UcmFuc2Zvcm06XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnaG1zJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBEb3dubG9hZCBidXR0b24gZm9yIHBkZiByZXNvdXJjZXMgLS0+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzaG91bGRTaG93RG93bmxvYWRCdXR0b24oY29udGVudClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkb3dubG9hZC1idG4gbWF0LWJvZHktMiBtdC0yIHNtOm10LTFcIiAoY2xpY2spPVwiZG93bmxvYWRDb250ZW50KGNvbnRlbnQsICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnYWN0aXZlJzogcGF0aFNldD8uaGFzKGNvbnRlbnQ/LmlkZW50aWZpZXIpfVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwiZG93bmxvYWQtbGluayBmbGV4IGl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIlwiPkRvd25sb2FkPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9uZy1jb250YWluZXI+XG5cbjxtYXQtbWVudSAjYnV0dG9uTWVudT1cIm1hdE1lbnVcIj5cbiAgICA8YSBtYXQtbWVudS1pdGVtIFtyb3V0ZXJMaW5rXT1cIicuLi8nICsgY29udGVudD8uaWRlbnRpZmllciArICcvb3ZlcnZpZXcnXCIgW3F1ZXJ5UGFyYW1zXT1cImNvbnRleHRQYXRoXCJcbiAgICAgICAgY2xhc3M9XCJmbGV4IGZsZXgtbWlkZGxlXCI+XG4gICAgICAgIDxtYXQtaWNvbj50b2M8L21hdC1pY29uPlxuICAgICAgICA8aDMgY2xhc3M9XCJtYXJnaW4tcmVtb3ZlIG5vZHRyYW5zbGF0ZVwiPlxuICAgICAgICAgICAgVmlldyBEZXRhaWxzXG4gICAgICAgIDwvaDM+XG4gICAgPC9hPlxuPC9tYXQtbWVudT5cblxuPG5nLXRlbXBsYXRlICNjb2xsZWN0aW9uVGVtcGxhdGU+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzQ29sbGVjdGlvblwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY29sbGVjdGlvbi13cmFwcGVyIHAtNCBmbGV4IGZsZXgtY29sIHBvc2l0aW9uLXJlbGF0aXZlXCIgW25nQ2xhc3NdPVwieydvcGVuJzogY2hlY2soY29udGVudCksXG4gICAgICAgICAgICAnY2xvc2UnOiAhY29udGVudC52aWV3Q2hpbGRyZW4sXG4gICAgICAgICAgICAnY291cnNlJzohaXNNb2R1bGUsICdtb2R1bGUnOiBpc01vZHVsZSxcbiAgICAgICAgICAgICdjb250ZW50LWFjdGl2ZSc6IHBhdGhTZXQ/Lmhhcyhjb250ZW50LmlkZW50aWZpZXIpICYmIGlzRW5yb2xsZWR9XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FyZC1jb2xsZWN0aW9uIHctYXV0byBzbTp3LTEwMCBwYWRkaW5nLXJpZ2h0LXhsXCI+XG4gICAgICAgICAgICAgICAgPCEtLSA8aW1nIGNsYXNzPVwiY2FyZC10aHVtYm5haWwgd3MtbWF0LXByaW1hcnktbGl0ZS1iYWNrZ3JvdW5kXCIgW3NyY109XCJjb250ZW50Py5hcHBJY29uXCIgYWx0PVwiVGh1bWJuYWlsXCJcbiAgICAgICAgICAgIChjbGljayk9XCJjb250ZW50LnZpZXdDaGlsZHJlbiA9ICFjb250ZW50LnZpZXdDaGlsZHJlblwiIFt3c1V0aWxzRGVmYXVsdFRodW1ibmFpbF09XCJkZWZhdWx0VGh1bWJuYWlsXCIgLz4gLS0+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2wgZmxleC13cmFwIGZsZXgtYmV0d2VlbiB3aWR0aC1leHBhbmQgcHItMCB3LTEwMCBcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtdHJ1bmNhdGVcIiBbbmdDbGFzc109XCJ7J2N1cnNvci1wb2ludGVyJzogIWlzRW5hYmxlZH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNvbnRlbnQudmlld0NoaWxkcmVuID0gIWNvbnRlbnQudmlld0NoaWxkcmVuXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgbWItMSBzbTpmbGV4LXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJpc01vZHVsZSAmJiBpc0Vucm9sbGVkICYmICFpc01pbGVzdG9uZUxvY2tlZCAmJiAhaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCIhZm9yUHJldmlldyAmJiBjb250ZW50Py5pZGVudGlmaWVyICYmIGdldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpIDsgZWxzZSBlbHNlQmxvY2tcIj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldENvbXBsZXRpb25TdGF0dXMoY29udGVudC5pZGVudGlmaWVyKSA9PSAyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbXBsZXRlZCBtci0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJjb21wbGV0ZWQtaWNvblwiIFtjb2xvcl09XCJibHVlXCI+Y2hlY2tfY2lyY2xlPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRDb21wbGV0aW9uU3RhdHVzKGNvbnRlbnQ/LmlkZW50aWZpZXIpIDwgMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxjaXJjbGUtcHJvZ3Jlc3MgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBwcm9ncmVzcyBtci0xXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BlcmNlbnRdPVwiZ2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcilcIiBbcmFkaXVzXT1cIjEwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlV2lkdGhdPVwiMlwiIFtpbm5lclN0cm9rZVdpZHRoXT1cIjJcIiBbc3BhY2VdPVwiLTJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3V0ZXJTdHJva2VDb2xvcl09XCJwcm9ncmVzc0NvbG9yMigpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lubmVyU3Ryb2tlQ29sb3JdPVwiJ3JnYmEoMCwgMCwgMCwgMC4xNiknXCIgW2FuaW1hdGlvbl09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2FuaW1hdGlvbkR1cmF0aW9uXT1cIjI1MFwiIFtzaG93VGl0bGVdPVwiZmFsc2VcIiBbc2hvd1VuaXRzXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dTdWJ0aXRsZV09XCJmYWxzZVwiIFtzaG93SW5uZXJTdHJva2VdPVwidHJ1ZVwiIFtjbG9ja3dpc2VdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtiYWNrZ3JvdW5kT3BhY2l0eV09XCIwXCIgW2JhY2tncm91bmRHcmFkaWVudF09XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtiYWNrZ3JvdW5kU3Ryb2tlV2lkdGhdPVwiM1wiIG1hdFRvb2x0aXA9XCJJbiBwcm9ncmVzc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93WmVyb091dGVyU3Ryb2tlXT1mYWxzZSBbYmFja2dyb3VuZFBhZGRpbmddPVwiLTdcIiBbc3RhcnRGcm9tWmVyb109XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtiYWNrZ3JvdW5kUGFkZGluZ109XCIwXCIgW2ltYWdlSGVpZ2h0XT1cIjE4XCIgW2ltYWdlV2lkdGhdPVwiMThcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2hvd0JhY2tncm91bmRdPVwiZmFsc2VcIiBbb3V0ZXJTdHJva2VMaW5lY2FwXT1cIididXR0J1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvY2lyY2xlLXByb2dyZXNzPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI2Vsc2VCbG9jaz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxjaXJjbGUtcHJvZ3Jlc3MgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBwcm9ncmVzcyBtci0xXCIgW3BlcmNlbnRdPVwiMFwiIFtyYWRpdXNdPVwiMTFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZVdpZHRoXT1cIjJcIiBbaW5uZXJTdHJva2VXaWR0aF09XCIyXCIgW291dGVyU3Ryb2tlQ29sb3JdPVwiJyM4MDgwODAnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaW5uZXJTdHJva2VDb2xvcl09XCInIzgwODA4MCdcIiBbYW5pbWF0aW9uXT1cInRydWVcIiBbc3BhY2VdPVwiLTJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93VW5pdHNdPVwiZmFsc2VcIiBbYW5pbWF0aW9uRHVyYXRpb25dPVwiMjUwXCIgW3Nob3dUaXRsZV09XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2JhY2tncm91bmRQYWRkaW5nXT1cIjBcIiBbYmFja2dyb3VuZFBhZGRpbmddPVwiLTlcIiBbb3V0ZXJTdHJva2VMaW5lY2FwXT1cIididXR0J1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcD1cIk5vdCBzdGFydGVkXCIgW3Nob3dTdWJ0aXRsZV09XCJmYWxzZVwiIFtzaG93SW5uZXJTdHJva2VdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Nsb2Nrd2lzZV09XCJ0cnVlXCIgW2ltYWdlSGVpZ2h0XT1cIjIyXCIgW2ltYWdlV2lkdGhdPVwiMjJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93QmFja2dyb3VuZF09XCJmYWxzZVwiPjwvY2lyY2xlLXByb2dyZXNzPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydjb2xsZWN0aW9uLWFjdGl2ZS1jbGFzcyc6IHBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKSAmJiBpc0Vucm9sbGVkfVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgKm5nSWY9XCJpc01pbGVzdG9uZUxvY2tlZFwiIHNyYz1cImFzc2V0cy9pY29ucy9odWJzL2xvY2suc3ZnXCIgYWx0PVwiTG9ja2VkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJsb2NrLWljb24gbXItMiBtYXJnaW4tYm90dG9tLXh4c1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4LWF1dG8gZmxleCBmbGV4LWNvbFwiIHN0eWxlPVwibWluLXdpZHRoOiAwO1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cIm1hcmdpbi1yZW1vdmUgdGV4dC10cnVuY2F0ZSBtYXQtc3ViaGVhZGluZy0xIGZvbnQtYm9sZCBub2R0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieyd0ZXh0LWFjdGl2ZSc6IHBhdGhTZXQ/Lmhhcyhjb250ZW50LmlkZW50aWZpZXIpICYmIGlzRW5yb2xsZWR9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttYXRUb29sdGlwXT1cImNvbnRlbnQ/Lm5hbWU/Lmxlbmd0aCA+IDUwID8gY29udGVudD8ubmFtZSA6ICcnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXBQb3NpdGlvbj1cImFib3ZlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj57e2lzTWlsZXN0b25lID8gaW5kZXggLTEgOiBpbmRleH19LiA8L3NwYW4+e3sgY29udGVudD8ubmFtZSB8IHRydW5jYXRlOjUwIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTFcIiAqbmdJZj1cImlzTWlsZXN0b25lICYmIGlzTWlsZXN0b25lTG9ja2VkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImxvY2tlZC10ZXh0XCI+TG9ja2VkPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTFcIiAqbmdJZj1cImNvbnRlbnQ/LmlzTWFuZGF0b3J5XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1hbmRhdG9yeS10ZXh0IG1hdC1jYXB0aW9uXCI+TWFuZGF0b3J5PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidHlwZS1jb250YWluZXIgcmVzb3VyY2UgbXQtMiBzbTptdC0wXCIgKm5nSWY9XCJjb250ZW50Py5jYXRlZ29yeSA9PT0gJ1Jlc291cmNlJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJtci0xIGN1c3RvbS1pY29uIHJvdGF0ZS05MFwiPmNhbGxfdG9fYWN0aW9uPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJub2R0cmFuc2xhdGVcIj5SZXNvdXJjZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidHlwZS1jb250YWluZXIgbW9kdWxlIG10LTIgc206bXQtMFwiICpuZ0lmPVwiY29udGVudD8uY2F0ZWdvcnkgPT09ICdDb2xsZWN0aW9uJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJtci0xIGN1c3RvbS1pY29uIHJvdGF0ZS05MFwiPmNhbGxfdG9fYWN0aW9uPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJub2R0cmFuc2xhdGVcIj5Nb2R1bGU8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInR5cGUtY29udGFpbmVyIGNvdXJzZSBtdC0yIHNtOm10LTBcIiAqbmdJZj1cImNvbnRlbnQ/LmNhdGVnb3J5ID09PSAnQ291cnNlJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJtci0xIGN1c3RvbS1pY29uIHJvdGF0ZS05MFwiPmNhbGxfdG9fYWN0aW9uPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJub2R0cmFuc2xhdGVcIj5Db3Vyc2U8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gTWlsZXN0b25lIEJhZGdlIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImlzTWlsZXN0b25lXCIgY2xhc3M9XCJtaWxlc3RvbmUtYmFkZ2UgbXQtMiBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtaWxlc3RvbmUtYmFkZ2UtdGV4dCBub2R0cmFuc2xhdGVcIj5NaWxlc3RvbmUge3tpbmRleCAtIDF9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBNaWxlc3RvbmUgRGVzY3JpcHRpb24gKDIgbGluZXMgd2l0aCBlbGxpcHNpcykgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8cCAjbWlsZXN0b25lRGVzY1JlZiAqbmdJZj1cImlzTWlsZXN0b25lICYmIGNvbnRlbnQ/LmRlc2NyaXB0aW9uXCIgY2xhc3M9XCJtaWxlc3RvbmUtZGVzY3JpcHRpb24gbXQtMiBub2R0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttYXRUb29sdGlwXT1cImlzTXVsdGlMaW5lVHJ1bmNhdGVkKG1pbGVzdG9uZURlc2NSZWYpID8gY29udGVudD8uZGVzY3JpcHRpb24gOiAnJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcFBvc2l0aW9uPVwiYWJvdmVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXBDbGFzcz1cIm11bHRpbGluZS10b29sdGlwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgY29udGVudD8uZGVzY3JpcHRpb24gfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtcm93IGdhcC0zIGl0ZW1zLWNlbnRlciBjb250ZW50LWtleS12YWx1ZXMgbXQtMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIiFpc01vZHVsZVwiIGFsdD1cImNvdXJzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidGltZS1pY29uIGljb24tY29sb3JcIj52aWRlb19saWJyYXJ5PC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nICpuZ0lmPVwiaXNNb2R1bGVcIiBhbHQ9XCJNb2R1bGVcIiBjbGFzcz1cInRpbWUtaWNvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L21vZHVsZS5zdmdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC14cyBub2R0cmFuc2xhdGVcIj57eyAoaGllcmFyY2h5TWFwRGF0YVtjb250ZW50Py5pZGVudGlmaWVyXT8uZHVyYXRpb24gfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMTIwKXxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGlwZUR1cmF0aW9uVHJhbnNmb3JtOiAnaG1zJyB9fTwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnQ/Lm1vZHVsZUNvdW50XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJwZXJpb2RcIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC14cyBub2R0cmFuc2xhdGVcIj57e2NvbnRlbnQ/Lm1vZHVsZUNvdW50fX0ge3tjb250ZW50Py5tb2R1bGVDb3VudCA+IDE/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbW9kdWxlcycgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ21vZHVsZSd9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb250ZW50Py5sZWFmTm9kZXNDb3VudFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicGVyaW9kXCI+PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQteHMgbm9kdHJhbnNsYXRlXCI+e3tjb250ZW50Py5sZWFmTm9kZXNDb3VudH19IHt7Y29udGVudD8ubGVhZk5vZGVzQ291bnRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4xID8gJ2l0ZW1zJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdpdGVtJ319PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gTWlsZXN0b25lIENvbXBsZXRpb24gUHJvZ3Jlc3MgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaXNNaWxlc3RvbmUgJiYgaXNFbnJvbGxlZCAmJiAhaXNNaWxlc3RvbmVMb2NrZWRcIiBjbGFzcz1cIm1pbGVzdG9uZS1wcm9ncmVzcyBtdC0yICBmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWJldHdlZW5cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1pbGVzdG9uZS1wcm9ncmVzcy10ZXh0IG5vZHRyYW5zbGF0ZVwiPnt7Z2V0TWlsZXN0b25lQ29tcGxldGVkQ291bnQoKX19IG9mXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7Y29udGVudD8ubGVhZk5vZGVzQ291bnQgfHwgMH19IGNvbXBsZXRlZDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFZpZXcgQWNoaWV2ZW1lbnQgQnV0dG9uIGZvciBjb21wbGV0ZWQgbWlsZXN0b25lcyAtIE91dHNpZGUgY2xpY2thYmxlIGFyZWEgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImlzTWlsZXN0b25lICYmIGlzRW5yb2xsZWQgJiYgKGdldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpID49IDEwMCB8fCBnZXRDb21wbGV0aW9uU3RhdHVzKGNvbnRlbnQ/LmlkZW50aWZpZXIpID09PSAyKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidmlldy1hY2hpZXZlbWVudC1jb250YWluZXIgbXQtMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInZpZXctYWNoaWV2ZW1lbnQtYnRuXCIgW2Rpc2FibGVkXT1cImFjaGlldmVtZW50TG9hZGluZ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwidmlld01pbGVzdG9uZUFjaGlldmVtZW50KCRldmVudClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiIWFjaGlldmVtZW50TG9hZGluZ1wiPlZpZXcgQWNoaWV2ZW1lbnQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNwaW5uZXIgKm5nSWY9XCJhY2hpZXZlbWVudExvYWRpbmdcIiBbZGlhbWV0ZXJdPVwiMTZcIiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3Ryb2tlV2lkdGhdPVwiMlwiIGNvbG9yPVwicHJpbWFyeVwiIGNsYXNzPVwiaW5saW5lLXNwaW5uZXJcIj48L21hdC1zcGlubmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBVbmxvY2sgQ3JpdGVyaWEgTWVzc2FnZSBmb3IgTG9ja2VkIE1pbGVzdG9uZXMgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaXNNaWxlc3RvbmUgJiYgaXNFbnJvbGxlZCAmJiBpc01pbGVzdG9uZUxvY2tlZFwiIGNsYXNzPVwibWlsZXN0b25lLWxvY2tlZC1tZXNzYWdlIG10LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImxvY2tlZC1jcml0ZXJpYS10ZXh0IG1hdC1jYXB0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGdldE1pbGVzdG9uZVVubG9ja01lc3NhZ2UoKSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8IS0tIEZvciBjb3Vyc2UgcHJvZ3Jlc3MgdG8gYmUgc2hvd24gLS0+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc0Vucm9sbGVkICYmICFpc01pbGVzdG9uZUxvY2tlZCAmJiAhaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIiFmb3JQcmV2aWV3ICYmIGNvbnRlbnQ/LmlkZW50aWZpZXIgJiYgZ2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcikgJiYgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09ICdDb3Vyc2UnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldENvbXBsZXRpb25TdGF0dXMoY29udGVudD8uaWRlbnRpZmllcikgPT0gMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdC0yIG1yLTQgIGZsZXggZmxleC0xIGZsZXgtY29sICBwcm9ncmVzcy1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXJvdyBqdXN0aWZ5LWVuZCB3LWZ1bGwgXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWF0LWJvZHktMiBub2R0cmFuc2xhdGUgXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2dldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpfX0lPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHdzLXdpZGdldC1jb250ZW50LXByb2dyZXNzIFtjb250ZW50SWRdPVwiY29udGVudD8ucHJvZ3Jlc3NcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcHJvZ3Jlc3NdPVwiZ2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcilcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcHJvZ3Jlc3NUeXBlXT1cIidwZXJjZW50YWdlJ1wiIFtjdXN0b21DbGFzc05hbWVdPVwiJ3ZpZXdlci1wcm9ncmVzcydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3dzLXdpZGdldC1jb250ZW50LXByb2dyZXNzPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudD8uaXNzdWVkQ2VydGlmaWNhdGVzSWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YSBjbGFzcz1cIm1sLTUgY2VydGlmaWNhdGUtYnRuXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydkaXNhYmxlLWJ0bic6IGRvd25sb2FkQ2VydGlmaWNhdGVMb2FkaW5nIHx8IGNvbnRlbnQ/Lmlzc3VlZENlcnRpZmljYXRlc0lkfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCIhZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmcgJiYgZG93bmxvYWRDZXJ0aWZpY2F0ZShjb250ZW50Py5pc3N1ZWRDZXJ0aWZpY2F0ZXNJZCk7JGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPGltZyBzcmM9XCJmdXNpb24tYXNzZXRzL2ltYWdlcy9jZXJ0aWZpY2F0ZS1pY28uc3ZnXCIgd2lkdGg9XCIyNFwiIGhlaWdodD1cIjI0XCI+IC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5vZHRyYW5zbGF0ZVwiPkNlcnRpZmljYXRlPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCIhZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJtbC0yXCI+YXJyb3dfZG93bndhcmQ8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2VudGVyIGZsZXggZmxleC1taWRkbGUgY2VydGlmaWNhdGUtbG9hZGVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtc3Bpbm5lciBzdHJva2VXaWR0aD1cIjJcIiBzdHJva2U9XCInd2hpdGUnXCIgY2xhc3M9XCJ3aGl0ZS1zcGlubmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGlhbWV0ZXJdPVwiMTZcIj48L21hdC1zcGlubmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPGNpcmNsZS1wcm9ncmVzcyBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHByb2dyZXNzXCIgW3BlcmNlbnRdPVwiMTAwXCIgW3JhZGl1c109XCIxMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3V0ZXJTdHJva2VXaWR0aF09XCIzXCIgW2lubmVyU3Ryb2tlV2lkdGhdPVwiM1wiIFtzcGFjZV09XCItM1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3V0ZXJTdHJva2VDb2xvcl09XCJwcm9ncmVzc0NvbG9yKClcIiBbaW5uZXJTdHJva2VDb2xvcl09XCIncmdiYSgwLDAsMCwuMTYpJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYW5pbWF0aW9uXT1cInRydWVcIiBbYW5pbWF0aW9uRHVyYXRpb25dPVwiMzAwXCIgW3Nob3dUaXRsZV09XCJmYWxzZVwiIFtzaG93VW5pdHNdPVwiZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dTdWJ0aXRsZV09XCJmYWxzZVwiIFtzaG93SW5uZXJTdHJva2VdPVwidHJ1ZVwiIFtjbG9ja3dpc2VdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYmFja2dyb3VuZE9wYWNpdHldPVwiMFwiIFtiYWNrZ3JvdW5kR3JhZGllbnRdPVwiZmFsc2VcIiBbYmFja2dyb3VuZFN0cm9rZVdpZHRoXT1cIjNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3daZXJvT3V0ZXJTdHJva2VdPWZhbHNlIFtiYWNrZ3JvdW5kUGFkZGluZ109XCItOVwiIFtzdGFydEZyb21aZXJvXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtiYWNrZ3JvdW5kUGFkZGluZ109XCIwXCIgW2ltYWdlSGVpZ2h0XT1cIjI0XCIgW2ltYWdlV2lkdGhdPVwiMjRcIiBbc2hvd0JhY2tncm91bmRdPVwiZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlTGluZWNhcF09XCInYnV0dCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9jaXJjbGUtcHJvZ3Jlc3M+IC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRDb21wbGV0aW9uU3RhdHVzKGNvbnRlbnQ/LmlkZW50aWZpZXIpIDwgMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdC0yIG1yLTQgIGZsZXggZmxleC0xIGZsZXgtY29sICBwcm9ncmVzcy1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXJvdyBqdXN0aWZ5LWVuZCB3LWZ1bGwgd3MtbWF0LWJsYWNrLXRleHRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtYXQtYm9keS0yICB3cy1tYXQtYmxhY2stdGV4dCBub2R0cmFuc2xhdGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7Z2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcil9fSU8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8d3Mtd2lkZ2V0LWNvbnRlbnQtcHJvZ3Jlc3MgW2NvbnRlbnRJZF09XCJjb250ZW50Py5wcm9ncmVzc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwcm9ncmVzc109XCJnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwcm9ncmVzc1R5cGVdPVwiJ3BlcmNlbnRhZ2UnXCIgW2N1c3RvbUNsYXNzTmFtZV09XCIndmlld2VyLXByb2dyZXNzJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvd3Mtd2lkZ2V0LWNvbnRlbnQtcHJvZ3Jlc3M+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb250ZW50Py5pc3N1ZWRDZXJ0aWZpY2F0ZXNJZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwibWwtNSBjZXJ0aWZpY2F0ZS1idG5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J2Rpc2FibGUtYnRuJzogZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmcgfHwgY29udGVudD8uaXNzdWVkQ2VydGlmaWNhdGVzSWR9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIiFkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZyAmJiBkb3dubG9hZENlcnRpZmljYXRlKGNvbnRlbnQ/Lmlzc3VlZENlcnRpZmljYXRlc0lkKTskZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSA8aW1nIHNyYz1cImZ1c2lvbi1hc3NldHMvaW1hZ2VzL2NlcnRpZmljYXRlLWljby5zdmdcIiB3aWR0aD1cIjI0XCIgaGVpZ2h0PVwiMjRcIj4gLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibm9kdHJhbnNsYXRlXCI+Q2VydGlmaWNhdGU8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIiFkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1sLTJcIj5hcnJvd19kb3dud2FyZDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjZW50ZXIgZmxleCBmbGV4LW1pZGRsZSBjZXJ0aWZpY2F0ZS1sb2FkZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zcGlubmVyIHN0cm9rZVdpZHRoPVwiMlwiIHN0cm9rZT1cIid3aGl0ZSdcIiBjbGFzcz1cIndoaXRlLXNwaW5uZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaWFtZXRlcl09XCIxNlwiPjwvbWF0LXNwaW5uZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VlLWFsbC1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxhIGhyZWY9XCJqYXZhc2NyaXB0OnZvaWQoMClcIiByb2xlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiY29udGVudC52aWV3Q2hpbGRyZW4gPSAhY29udGVudC52aWV3Q2hpbGRyZW47IGV4cGFuZEFjdGl2ZSA9IGZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInNlZS1hbGwtYnRuIHRhYiBjdXN0b20tY2hldnJvbiBjdXN0b21pY29uXCIgbWF0LWJ1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCIhY29udGVudC52aWV3Q2hpbGRyZW4gJiYgIWlzTW9kdWxlXCI+a2V5Ym9hcmRfYXJyb3dfZG93bjwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwiY29udGVudC52aWV3Q2hpbGRyZW4gJiYgIWlzTW9kdWxlXCI+a2V5Ym9hcmRfYXJyb3dfdXA8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIiFjb250ZW50LnZpZXdDaGlsZHJlbiAmJiBpc01vZHVsZVwiPmFkZDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwiY29udGVudC52aWV3Q2hpbGRyZW4gJiYgaXNNb2R1bGVcIj5yZW1vdmU8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNoaWxkLXdyYXBwZXIgIFwiICpuZ0lmPVwiY29udGVudC52aWV3Q2hpbGRyZW5cIiBbbmdDbGFzc109XCJ7J29wZW4nOiBjb250ZW50LnZpZXdDaGlsZHJlbixcbiAgICAgICAgICAgICdjbG9zZSc6ICFjb250ZW50LnZpZXdDaGlsZHJlbixcbiAgICAgICAgICAgICdjb3Vyc2UnOiFpc01vZHVsZSxcbiAgICAgICAgICAgICdtb2R1bGUnOiBpc01vZHVsZX1cIiBbQHBhbmVsSW5PdXRdPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNoaWxkcmVuLWNvbnRhaW5lclwiIFtuZ0NsYXNzXT1cInsnbW9kdWxlJzogaXNNb2R1bGUsICcnOiAhaXNNb2R1bGV9XCI+XG4gICAgICAgICAgICAgICAgPHdzLXdpZGdldC1hcHAtdG9jLWNvbnRlbnQtY2FyZC12MiBbZm9yUHJldmlld109XCJmb3JQcmV2aWV3XCIgW2NvbXBvbmVudE5hbWVdPVwiY29tcG9uZW50TmFtZVwiXG4gICAgICAgICAgICAgICAgICAgIFtjb250ZW50XT1cImNoaWxkXCIgW2V4cGFuZEFsbF09XCJleHBhbmRBbGxcIiBbcm9vdElkXT1cInJvb3RJZFwiIFtiYXRjaElkXT1cImJhdGNoSWRcIlxuICAgICAgICAgICAgICAgICAgICBbcm9vdENvbnRlbnRUeXBlXT1cInJvb3RDb250ZW50VHlwZVwiIFtpbmRleF09XCJqKzFcIiBbYmFzZUNvbnRlbnRSZWFkRGF0YV09XCJiYXNlQ29udGVudFJlYWREYXRhXCJcbiAgICAgICAgICAgICAgICAgICAgW3BhdGhTZXRdPVwicGF0aFNldFwiIFtoaWVyYXJjaHlNYXBEYXRhXT1cImhpZXJhcmNoeU1hcERhdGFcIiBbYmF0Y2hEYXRhXT1cImJhdGNoRGF0YVwiXG4gICAgICAgICAgICAgICAgICAgIFttbENvdXJzZV09XCJtbENvdXJzZVwiIFtwYXJlbnRNaWxlc3RvbmVMb2NrZWRdPVwiaXNNaWxlc3RvbmVMb2NrZWQgfHwgaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWRcIlxuICAgICAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgY2hpbGQgb2YgY29udGVudD8uY2hpbGRyZW47IHRyYWNrQnk6IGNvbnRlbnRUcmFja0J5OyBsZXQgaj0gaW5kZXg7bGV0IGlzRmlyc3QgPSBmaXJzdFwiXG4gICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnbW9kdWxlQ2FyZCc6IGNoZWNrSXNNb2R1bGUoY2hpbGQpLCAncmVzb3VyY2VDYXJkJzogIWNoZWNrSXNNb2R1bGUoY2hpbGQpLCAnZmlyc3QnOiBpc0ZpcnN0fVwiPlxuICAgICAgICAgICAgICAgIDwvd3Mtd2lkZ2V0LWFwcC10b2MtY29udGVudC1jYXJkLXYyPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvbmctY29udGFpbmVyPlxuPC9uZy10ZW1wbGF0ZT5cblxuXG48bmctY29udGFpbmVyICpuZ0lmPVwiaXNQcmVBc3Nlc3NtZW50XCI+XG4gICAgPGRpdiBjbGFzcz1cImNvbGxlY3Rpb24td3JhcHBlciBwLTQgZmxleCBmbGV4LWNvbCBwb3NpdGlvbi1yZWxhdGl2ZVwiIFtuZ0NsYXNzXT1cInsnb3Blbic6IGNoZWNrKGNvbnRlbnQpLFxuICAgICAgICAnY291cnNlJzohaXNNb2R1bGUsICdtb2R1bGUnOiBpc01vZHVsZSxcbiAgICAgICAgJ2NvbnRlbnQtYWN0aXZlJzogcGF0aFNldD8uaGFzKGNvbnRlbnQuaWRlbnRpZmllcil9XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjYXJkLWNvbGxlY3Rpb24gdy1hdXRvIHNtOnctMTAwIHBhZGRpbmctcmlnaHQteGxcIj5cbiAgICAgICAgICAgIDwhLS0gPGltZyBjbGFzcz1cImNhcmQtdGh1bWJuYWlsIHdzLW1hdC1wcmltYXJ5LWxpdGUtYmFja2dyb3VuZFwiIFtzcmNdPVwiY29udGVudD8uYXBwSWNvblwiIGFsdD1cIlRodW1ibmFpbFwiXG4gICAgICAgIChjbGljayk9XCJjb250ZW50LnZpZXdDaGlsZHJlbiA9ICFjb250ZW50LnZpZXdDaGlsZHJlblwiIFt3c1V0aWxzRGVmYXVsdFRodW1ibmFpbF09XCJkZWZhdWx0VGh1bWJuYWlsXCIgLz4gLS0+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCBmbGV4LXdyYXAgZmxleC1iZXR3ZWVuIHdpZHRoLWV4cGFuZCBwci0wIHctMTAwIFwiPlxuXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtdHJ1bmNhdGVcIiBbbmdDbGFzc109XCJ7J2N1cnNvci1wb2ludGVyJzogIWlzRW5hYmxlZH1cIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiY29udGVudC52aWV3Q2hpbGRyZW4gPSAhY29udGVudC52aWV3Q2hpbGRyZW5cIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggc206ZmxleC1yb3cgZmxleC13cmFwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCIhZm9yUHJldmlldyAmJiBjb250ZW50Py5pZGVudGlmaWVyICYmIGdldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpIDsgZWxzZSBlbHNlQmxvY2tcIj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0Q29tcGxldGlvblN0YXR1cyhjb250ZW50LmlkZW50aWZpZXIpID09IDJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb21wbGV0ZWQgbXItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cImNvbXBsZXRlZC1pY29uXCIgW2NvbG9yXT1cImJsdWVcIj5jaGVja19jaXJjbGU8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0Q29tcGxldGlvblN0YXR1cyhjb250ZW50Py5pZGVudGlmaWVyKSA8IDJcIj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZS1wcm9ncmVzcyBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHByb2dyZXNzIG1yLTFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwZXJjZW50XT1cImdldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpXCIgW3JhZGl1c109XCIxMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlV2lkdGhdPVwiMlwiIFtpbm5lclN0cm9rZVdpZHRoXT1cIjJcIiBbc3BhY2VdPVwiLTJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZUNvbG9yXT1cInByb2dyZXNzQ29sb3IyKClcIiBbaW5uZXJTdHJva2VDb2xvcl09XCIncmdiYSgwLCAwLCAwLCAwLjE2KSdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthbmltYXRpb25dPVwidHJ1ZVwiIFthbmltYXRpb25EdXJhdGlvbl09XCIyNTBcIiBbc2hvd1RpdGxlXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2hvd1VuaXRzXT1cImZhbHNlXCIgW3Nob3dTdWJ0aXRsZV09XCJmYWxzZVwiIFtzaG93SW5uZXJTdHJva2VdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Nsb2Nrd2lzZV09XCJ0cnVlXCIgW2JhY2tncm91bmRPcGFjaXR5XT1cIjBcIiBbYmFja2dyb3VuZEdyYWRpZW50XT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYmFja2dyb3VuZFN0cm9rZVdpZHRoXT1cIjNcIiBtYXRUb29sdGlwPVwiSW4gcHJvZ3Jlc3NcIiBbc2hvd1plcm9PdXRlclN0cm9rZV09ZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYmFja2dyb3VuZFBhZGRpbmddPVwiLTdcIiBbc3RhcnRGcm9tWmVyb109XCJmYWxzZVwiIFtiYWNrZ3JvdW5kUGFkZGluZ109XCIwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaW1hZ2VIZWlnaHRdPVwiMThcIiBbaW1hZ2VXaWR0aF09XCIxOFwiIFtzaG93QmFja2dyb3VuZF09XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlTGluZWNhcF09XCInYnV0dCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvY2lyY2xlLXByb2dyZXNzPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI2Vsc2VCbG9jaz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZS1wcm9ncmVzcyBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHByb2dyZXNzIG1yLTFcIiBbcGVyY2VudF09XCIwXCIgW3JhZGl1c109XCIxMVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3V0ZXJTdHJva2VXaWR0aF09XCIyXCIgW2lubmVyU3Ryb2tlV2lkdGhdPVwiMlwiIFtvdXRlclN0cm9rZUNvbG9yXT1cIicjODA4MDgwJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaW5uZXJTdHJva2VDb2xvcl09XCInIzgwODA4MCdcIiBbYW5pbWF0aW9uXT1cInRydWVcIiBbc3BhY2VdPVwiLTJcIiBbc2hvd1VuaXRzXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthbmltYXRpb25EdXJhdGlvbl09XCIyNTBcIiBbc2hvd1RpdGxlXT1cImZhbHNlXCIgW2JhY2tncm91bmRQYWRkaW5nXT1cIjBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2JhY2tncm91bmRQYWRkaW5nXT1cIi05XCIgW291dGVyU3Ryb2tlTGluZWNhcF09XCInYnV0dCdcIiBtYXRUb29sdGlwPVwiTm90IHN0YXJ0ZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dTdWJ0aXRsZV09XCJmYWxzZVwiIFtzaG93SW5uZXJTdHJva2VdPVwidHJ1ZVwiIFtjbG9ja3dpc2VdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaW1hZ2VIZWlnaHRdPVwiMjJcIiBbaW1hZ2VXaWR0aF09XCIyMlwiIFtzaG93QmFja2dyb3VuZF09XCJmYWxzZVwiPjwvY2lyY2xlLXByb2dyZXNzPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgW25nQ2xhc3NdPVwieydjb2xsZWN0aW9uLWFjdGl2ZS1jbGFzcyc6IHBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKX1cIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPHAgY2xhc3M9XCJtYXJnaW4tcmVtb3ZlIHRleHQtdHJ1bmNhdGUgbWF0LXN1YmhlYWRpbmctMSBmbGV4LWF1dG8gZm9udC1ib2xkIG5vZHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieyd0ZXh0LWFjdGl2ZSc6IHBhdGhTZXQ/Lmhhcyhjb250ZW50LmlkZW50aWZpZXIpfVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7aW5kZXh9fS4ge3sgY29udGVudD8ubmFtZSB8IHRydW5jYXRlOjUwIH19XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3A+IC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJtYXJnaW4tcmVtb3ZlIHRleHQtdHJ1bmNhdGUgbWF0LXN1YmhlYWRpbmctMSBmbGV4LWF1dG8gZm9udC1ib2xkIG5vZHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmRpc2FibGVkXT1cIm51bGxcIiBbbmdDbGFzc109XCJ7J21sLTMnOiBpc0Vucm9sbGVkfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3JvdXRlckxpbmtdPVwiKGlzQWxsb3dlZCAmJiAhZm9yUHJldmlldyAmJiBpc0VuYWJsZWQpID8gcmVzb3VyY2VMaW5rLnVybCA6IG51bGxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtxdWVyeVBhcmFtc109XCJjb21wdXRlZFF1ZXJ5UGFyYW1zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSB7e2NvbnRlbnQ/LmNvdXJzZUNhdGVnb3J5fX0gLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBbbmdDbGFzc109XCJ7J3Jlc291cmNlLWFjdGl2ZSc6IHBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKX1cIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC10cnVuY2F0ZSBcIiBbbmdDbGFzc109XCJ7J2N1cnNvci1wb2ludGVyJzogIWlzRW5hYmxlZH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwicmFpc2VUZWxlbWV0cnkoKTsgY2hhbmdlUmVzb3VyY2UoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCBzbTpmbGV4LXJvdyBmbGV4LXdyYXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwibWFyZ2luLXJlbW92ZSB0ZXh0LXRydW5jYXRlIG1hdC1ib2R5LTIgZmxleC1hdXRvIGZvbnQtYm9sZCBub2R0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsndGV4dC1hY3RpdmUnOiBwYXRoU2V0Py5oYXMoY29udGVudD8uaWRlbnRpZmllcil9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWF0VG9vbHRpcF09XCJjb250ZW50Py5uYW1lPy5sZW5ndGggPiA1MCA/IGNvbnRlbnQ/Lm5hbWUgOiAnJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcFBvc2l0aW9uPVwiYWJvdmVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIDxtYXQtaWNvbiBjbGFzcz1cIm1hcmdpbi1yaWdodC14cyByYWRpb2J0biB0aW1lLWljb25cIj5yYWRpb19idXR0b25fdW5jaGVja2VkIDwvbWF0LWljb24+IC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7aW5kZXh9fS4ge3sgY29udGVudD8ubmFtZSB8IHRydW5jYXRlOjUwIH19XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY29udGVudC10eXBlIG9wdGlvbmFsLXNwYW4gbm9kdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm9wdGlvbmFsUmVhZGluZ1wiPnt7ICdwbGF5ZXJicmllZi5vcHRpb25hbCcgfCB0cmFuc2xhdGUgfFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlY2FzZX19IDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gZm9yIGRlZmF1bHQgZ3JleSBpY29ucyAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFwYXRoU2V0Py5oYXMoY29udGVudD8uaWRlbnRpZmllcilcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZXNpY29ucyB3cy1tYXQtYmxhY2s2MC10ZXh0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS92aWRlby5zdmdcIiBhbHQ9XCJWaWRlb1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIiAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAndmlkZW8vbXA0JyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ3ZpZGVvL3gteW91dHViZScgfHxcbiAgICAgICAgICAgICAgICAgICAgICBjb250ZW50Py5taW1lVHlwZSA9PT0nYXBwbGljYXRpb24veC1tcGVnVVJMJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvYXVkaW8uc3ZnXCIgYWx0PVwiQXVkaW9cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2F1ZGlvL21wZWcnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9wZGYuc3ZnXCIgYWx0PVwiUERGXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9wZGYnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L3Jlc291cmNlLnN2Z1wiIGFsdD1cIlN1cnZleVwiIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vc3VydmV5J1wiPiAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2xpbmsuc3ZnXCIgYWx0PVwiSW50ZXJhY3RpdmVDb250ZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi92bmQuZWtzdGVwLmh0bWwtYXJjaGl2ZScgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICd0ZXh0L3gtdXJsJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvYXNzZXNzbWVudC5zdmdcIiBhbHQ9XCJBc3Nlc3NtZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9qc29uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3F1aXonIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLnN1bmJpcmQucXVlc3Rpb25zZXQnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9pbWFnZS5zdmdcIiBhbHQ9XCJJbWFnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnaW1hZ2UvcG5nJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2ltYWdlL2pwZWcnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9jb250ZW50X2NvcHkuc3ZnXCIgY2xhc3M9XCJjb250ZW50aWNvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsdD1cIkNvdXJzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5la3N0ZXAuY29udGVudC1jb2xsZWN0aW9uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3N1cnZleSdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L21vZHVsZS5zdmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCIgYWx0PVwib2ZmbGluZSBzZXNzaW9uc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL29mZmxpbmUnXCI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5GSU5BTF9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5DT01QX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlNUQU5EQUxPTkVfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuUFJBQ1RJQ0VfUkVTT1VSQ0VcIj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInJlc291cmNlRHVyYXRpb24gd3MtbWF0LWJsYWNrNjAtdGV4dCBub2R0cmFuc2xhdGVcIj57e1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudD8ubWF4UXVlc3Rpb25zIH19IHt7ICdwbGF5ZXJicmllZi5xdWVzdGlvbnMnIHwgdHJhbnNsYXRlIHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlY2FzZX19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhKGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuQ09NUF9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5TVEFOREFMT05FX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInJlc291cmNlRHVyYXRpb24gd3MtbWF0LWJsYWNrNjAtdGV4dCBub2R0cmFuc2xhdGVcIj57e1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvbnRlbnQ/LmR1cmF0aW9ufHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZXJhcmNoeU1hcERhdGFbY29udGVudD8uaWRlbnRpZmllcl0/LmV4cGVjdGVkRHVyYXRpb24gfHwgMCl8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXBlRHVyYXRpb25UcmFuc2Zvcm06XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnaG1zJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBmb3Igd2hpdGUgaWNvbnMgd2hlbiBjb250ZW50IGhpZ2hsaWdodGVkIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwicGF0aFNldD8uaGFzKGNvbnRlbnQ/LmlkZW50aWZpZXIpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVzaWNvbnMgd3MtbWF0LXdoaXRlLXRleHRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS92aWRlby5zdmdcIiBhbHQ9XCJWaWRlb1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIiAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAndmlkZW8vbXA0JyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ3ZpZGVvL3gteW91dHViZScgfHxcbiAgICAgICAgICAgICAgICAgICAgICBjb250ZW50Py5taW1lVHlwZSA9PT0nYXBwbGljYXRpb24veC1tcGVnVVJMJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L3doaXRlL2F1ZGlvLnN2Z1wiIGFsdD1cIkF1ZGlvXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhdWRpby9tcGVnJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L3doaXRlL3BkZi5zdmdcIiBhbHQ9XCJQREZcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3BkZidcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L3doaXRlL3Jlc291cmNlLnN2Z1wiIGFsdD1cIlN1cnZleVwiIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vc3VydmV5J1wiPiAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9saW5rLnN2Z1wiIGFsdD1cIkludGVyYWN0aXZlQ29udGVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLmVrc3RlcC5odG1sLWFyY2hpdmUnIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAndGV4dC94LXVybCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9hc3Nlc3NtZW50LnN2Z1wiIGFsdD1cIkFzc2Vzc21lbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL2pzb24nIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vcXVpeicgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi92bmQuc3VuYmlyZC5xdWVzdGlvbnNldCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2ltYWdlLnN2Z1wiIGFsdD1cIkltYWdlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdpbWFnZS9wbmcnIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnaW1hZ2UvanBlZydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9jb250ZW50X2NvcHkuc3ZnXCIgY2xhc3M9XCJjb250ZW50aWNvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsdD1cIkNvdXJzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5la3N0ZXAuY29udGVudC1jb2xsZWN0aW9uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3N1cnZleSdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9tb2R1bGUuc3ZnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiIGFsdD1cIm9mZmxpbmUgc2Vzc2lvbnNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9vZmZsaW5lJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkNPTVBfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuU1RBTkRBTE9ORV9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5QUkFDVElDRV9SRVNPVVJDRVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInJlc291cmNlRHVyYXRpb24gd3MtbWF0LXdoaXRlLXRleHQgbm9kdHJhbnNsYXRlXCI+e3tcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ/Lm1heFF1ZXN0aW9ucyB9fSB7eyAncGxheWVyYnJpZWYucXVlc3Rpb25zJyB8IHRyYW5zbGF0ZSB8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZWNhc2V9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIShjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkNPTVBfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuU1RBTkRBTE9ORV9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5QUkFDVElDRV9SRVNPVVJDRSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJyZXNvdXJjZUR1cmF0aW9uIHdzLW1hdC13aGl0ZS10ZXh0IG5vZHRyYW5zbGF0ZVwiPnt7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29udGVudD8uZHVyYXRpb258fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGllcmFyY2h5TWFwRGF0YVtjb250ZW50Py5pZGVudGlmaWVyXT8uZXhwZWN0ZWREdXJhdGlvbiB8fCAwKXxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpcGVEdXJhdGlvblRyYW5zZm9ybTpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdobXMnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPGRpdiBjbGFzcz1cInR5cGUtY29udGFpbmVyIHJlc291cmNlIG10LTIgc206bXQtMFwiICpuZ0lmPVwiY29udGVudD8uY2F0ZWdvcnkgPT09ICdSZXNvdXJjZSdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJtci0xIGN1c3RvbS1pY29uIHJvdGF0ZS05MFwiPmNhbGxfdG9fYWN0aW9uPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5vZHRyYW5zbGF0ZVwiPlJlc291cmNlPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidHlwZS1jb250YWluZXIgbW9kdWxlIG10LTIgc206bXQtMFwiICpuZ0lmPVwiY29udGVudD8uY2F0ZWdvcnkgPT09ICdDb2xsZWN0aW9uJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm1yLTEgY3VzdG9tLWljb24gcm90YXRlLTkwXCI+Y2FsbF90b19hY3Rpb248L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibm9kdHJhbnNsYXRlXCI+TW9kdWxlPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidHlwZS1jb250YWluZXIgY291cnNlIG10LTIgc206bXQtMFwiICpuZ0lmPVwiY29udGVudD8uY2F0ZWdvcnkgPT09ICdDb3Vyc2UnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwibXItMSBjdXN0b20taWNvbiByb3RhdGUtOTBcIj5jYWxsX3RvX2FjdGlvbjwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJub2R0cmFuc2xhdGVcIj5Db3Vyc2U8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj4gLS0+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPCEtLSBGb3IgY291cnNlIHByb2dyZXNzIHRvIGJlIHNob3duIC0tPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIWZvclByZXZpZXcgJiYgY29udGVudD8uaWRlbnRpZmllciAmJiBnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldENvbXBsZXRpb25TdGF0dXMoY29udGVudD8uaWRlbnRpZmllcikgPT0gMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtMiBtci00ICBmbGV4IGZsZXgtMSBmbGV4LWNvbCAgcHJvZ3Jlc3MtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXJvdyBqdXN0aWZ5LWVuZCB3LWZ1bGwgXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtYXQtYm9keS0yIG5vZHRyYW5zbGF0ZSBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKX19JTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8d3Mtd2lkZ2V0LWNvbnRlbnQtcHJvZ3Jlc3MgW2NvbnRlbnRJZF09XCJjb250ZW50Py5wcm9ncmVzc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Byb2dyZXNzXT1cImdldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcHJvZ3Jlc3NUeXBlXT1cIidwZXJjZW50YWdlJ1wiIFtjdXN0b21DbGFzc05hbWVdPVwiJ3ZpZXdlci1wcm9ncmVzcydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvd3Mtd2lkZ2V0LWNvbnRlbnQtcHJvZ3Jlc3M+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudD8uaXNzdWVkQ2VydGlmaWNhdGVzSWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwibWwtNSBjZXJ0aWZpY2F0ZS1idG5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnZGlzYWJsZS1idG4nOiBkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZyB8fCBjb250ZW50Py5pc3N1ZWRDZXJ0aWZpY2F0ZXNJZH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCIhZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmcgJiYgZG93bmxvYWRDZXJ0aWZpY2F0ZShjb250ZW50Py5pc3N1ZWRDZXJ0aWZpY2F0ZXNJZCk7JGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSA8aW1nIHNyYz1cImZ1c2lvbi1hc3NldHMvaW1hZ2VzL2NlcnRpZmljYXRlLWljby5zdmdcIiB3aWR0aD1cIjI0XCIgaGVpZ2h0PVwiMjRcIj4gLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJub2R0cmFuc2xhdGVcIj5DZXJ0aWZpY2F0ZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCIhZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1sLTJcIj5hcnJvd19kb3dud2FyZDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNlbnRlciBmbGV4IGZsZXgtbWlkZGxlIGNlcnRpZmljYXRlLWxvYWRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zcGlubmVyIHN0cm9rZVdpZHRoPVwiMlwiIHN0cm9rZT1cIid3aGl0ZSdcIiBjbGFzcz1cIndoaXRlLXNwaW5uZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2RpYW1ldGVyXT1cIjE2XCI+PC9tYXQtc3Bpbm5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSA8Y2lyY2xlLXByb2dyZXNzIGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgcHJvZ3Jlc3NcIiBbcGVyY2VudF09XCIxMDBcIiBbcmFkaXVzXT1cIjEyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlV2lkdGhdPVwiM1wiIFtpbm5lclN0cm9rZVdpZHRoXT1cIjNcIiBbc3BhY2VdPVwiLTNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3V0ZXJTdHJva2VDb2xvcl09XCJwcm9ncmVzc0NvbG9yKClcIiBbaW5uZXJTdHJva2VDb2xvcl09XCIncmdiYSgwLDAsMCwuMTYpJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthbmltYXRpb25dPVwidHJ1ZVwiIFthbmltYXRpb25EdXJhdGlvbl09XCIzMDBcIiBbc2hvd1RpdGxlXT1cImZhbHNlXCIgW3Nob3dVbml0c109XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93U3VidGl0bGVdPVwiZmFsc2VcIiBbc2hvd0lubmVyU3Ryb2tlXT1cInRydWVcIiBbY2xvY2t3aXNlXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYmFja2dyb3VuZE9wYWNpdHldPVwiMFwiIFtiYWNrZ3JvdW5kR3JhZGllbnRdPVwiZmFsc2VcIiBbYmFja2dyb3VuZFN0cm9rZVdpZHRoXT1cIjNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2hvd1plcm9PdXRlclN0cm9rZV09ZmFsc2UgW2JhY2tncm91bmRQYWRkaW5nXT1cIi05XCIgW3N0YXJ0RnJvbVplcm9dPVwiZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYmFja2dyb3VuZFBhZGRpbmddPVwiMFwiIFtpbWFnZUhlaWdodF09XCIyNFwiIFtpbWFnZVdpZHRoXT1cIjI0XCIgW3Nob3dCYWNrZ3JvdW5kXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlTGluZWNhcF09XCInYnV0dCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2NpcmNsZS1wcm9ncmVzcz4gLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRDb21wbGV0aW9uU3RhdHVzKGNvbnRlbnQ/LmlkZW50aWZpZXIpIDwgMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtMiBtci00ICBmbGV4IGZsZXgtMSBmbGV4LWNvbCAgcHJvZ3Jlc3MtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXJvdyBqdXN0aWZ5LWVuZCB3LWZ1bGwgd3MtbWF0LWJsYWNrLXRleHRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1hdC1ib2R5LTIgIHdzLW1hdC1ibGFjay10ZXh0IG5vZHRyYW5zbGF0ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2dldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpfX0lPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx3cy13aWRnZXQtY29udGVudC1wcm9ncmVzcyBbY29udGVudElkXT1cImNvbnRlbnQ/LnByb2dyZXNzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcHJvZ3Jlc3NdPVwiZ2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcilcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwcm9ncmVzc1R5cGVdPVwiJ3BlcmNlbnRhZ2UnXCIgW2N1c3RvbUNsYXNzTmFtZV09XCIndmlld2VyLXByb2dyZXNzJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC93cy13aWRnZXQtY29udGVudC1wcm9ncmVzcz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb250ZW50Py5pc3N1ZWRDZXJ0aWZpY2F0ZXNJZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJtbC01IGNlcnRpZmljYXRlLWJ0blwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydkaXNhYmxlLWJ0bic6IGRvd25sb2FkQ2VydGlmaWNhdGVMb2FkaW5nIHx8IGNvbnRlbnQ/Lmlzc3VlZENlcnRpZmljYXRlc0lkfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIiFkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZyAmJiBkb3dubG9hZENlcnRpZmljYXRlKGNvbnRlbnQ/Lmlzc3VlZENlcnRpZmljYXRlc0lkKTskZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIDxpbWcgc3JjPVwiZnVzaW9uLWFzc2V0cy9pbWFnZXMvY2VydGlmaWNhdGUtaWNvLnN2Z1wiIHdpZHRoPVwiMjRcIiBoZWlnaHQ9XCIyNFwiPiAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5vZHRyYW5zbGF0ZVwiPkNlcnRpZmljYXRlPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIiFkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwibWwtMlwiPmFycm93X2Rvd253YXJkPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2VudGVyIGZsZXggZmxleC1taWRkbGUgY2VydGlmaWNhdGUtbG9hZGVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNwaW5uZXIgc3Ryb2tlV2lkdGg9XCIyXCIgc3Ryb2tlPVwiJ3doaXRlJ1wiIGNsYXNzPVwid2hpdGUtc3Bpbm5lclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGlhbWV0ZXJdPVwiMTZcIj48L21hdC1zcGlubmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgIDwhLS0gPGRpdiBjbGFzcz1cInNlZS1hbGwtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxhIGhyZWY9XCJqYXZhc2NyaXB0OnZvaWQoMClcIiByb2xlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJjb250ZW50LnZpZXdDaGlsZHJlbiA9ICFjb250ZW50LnZpZXdDaGlsZHJlbjsgZXhwYW5kQWN0aXZlID0gZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJzZWUtYWxsLWJ0biB0YWIgY3VzdG9tLWNoZXZyb24gY3VzdG9taWNvblwiIG1hdC1idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCIhY29udGVudC52aWV3Q2hpbGRyZW4gJiYgIWlzTW9kdWxlXCI+a2V5Ym9hcmRfYXJyb3dfZG93bjwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCJjb250ZW50LnZpZXdDaGlsZHJlbiAmJiAhaXNNb2R1bGVcIj5rZXlib2FyZF9hcnJvd191cDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCIhY29udGVudC52aWV3Q2hpbGRyZW4gJiYgaXNNb2R1bGVcIj5hZGQ8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwiY29udGVudC52aWV3Q2hpbGRyZW4gJiYgaXNNb2R1bGVcIj5yZW1vdmU8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgPC9kaXY+IC0tPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG48L25nLWNvbnRhaW5lcj4iXX0=