@sunbird-cb/toc 0.0.9 → 0.0.10-mauritius

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 (346) hide show
  1. package/esm2022/lib/_collection/_common/ai-tutor/ai-tutor.component.mjs +1169 -0
  2. package/esm2022/lib/_collection/_common/ai-tutor/socket.service.mjs +121 -0
  3. package/esm2022/lib/_collection/_common/attendance-card/attendance-card.component.mjs +55 -55
  4. package/esm2022/lib/_collection/_common/attendance-card/attendance-card.module.mjs +126 -126
  5. package/esm2022/lib/_collection/_common/attendance-helper/attendance-helper.component.mjs +32 -32
  6. package/esm2022/lib/_collection/_common/attendance-helper/attendance-helper.module.mjs +85 -85
  7. package/esm2022/lib/_collection/_common/avatar-photo/avatar-photo.component.mjs +100 -100
  8. package/esm2022/lib/_collection/_common/avatar-photo/avatar-photo.module.mjs +48 -48
  9. package/esm2022/lib/_collection/_common/card-competency/card-competency.component.mjs +58 -0
  10. package/esm2022/lib/_collection/_common/card-competency/card-competency.module.mjs +22 -0
  11. package/esm2022/lib/_collection/_common/card-content-v2/card-content-v2.model.mjs +23 -0
  12. package/esm2022/lib/_collection/_common/certificate-dialog/certificate-dialog.component.mjs +223 -120
  13. package/esm2022/lib/_collection/_common/certificate-dialog/certificate-dialog.module.mjs +96 -92
  14. package/esm2022/lib/_collection/_common/certificate-dialog/svg-to-pdf.component.mjs +48 -48
  15. package/esm2022/lib/_collection/_common/confirm-dialog/confirm-dialog.component.mjs +25 -25
  16. package/esm2022/lib/_collection/_common/confirm-dialog/confirm-dialog.module.mjs +41 -41
  17. package/esm2022/lib/_collection/_common/connection-hover-card/connection-hover-card.component.mjs +89 -89
  18. package/esm2022/lib/_collection/_common/connection-hover-card/connection-hover.module.mjs +42 -42
  19. package/esm2022/lib/_collection/_common/connection-hover-card/connection-hover.servive.mjs +41 -41
  20. package/esm2022/lib/_collection/_common/connection-name/connection-name.component.mjs +78 -78
  21. package/esm2022/lib/_collection/_common/connection-name/connection-name.module.mjs +45 -45
  22. package/esm2022/lib/_collection/_common/connection-name/profile-v2.model.mjs +2 -2
  23. package/esm2022/lib/_collection/_common/content-progress/content-progress.component.mjs +70 -70
  24. package/esm2022/lib/_collection/_common/content-progress/content-progress.module.mjs +28 -28
  25. package/esm2022/lib/_collection/_common/content-rating-v2-dialog/content-rating-v2-dialog.component.mjs +187 -187
  26. package/esm2022/lib/_collection/_common/content-rating-v2-dialog/content-rating-v2-dialog.module.mjs +86 -86
  27. package/esm2022/lib/_collection/_common/content-toc/ai-tutor-confirm-popup/ai-tutor-confirm-popup.component.mjs +31 -31
  28. package/esm2022/lib/_collection/_common/content-toc/app-toc-about/app-toc-about.component.mjs +961 -941
  29. package/esm2022/lib/_collection/_common/content-toc/app-toc-assignment-viewer/app-toc-assignment-viewer.component.mjs +183 -183
  30. package/esm2022/lib/_collection/_common/content-toc/app-toc-assignment-viewerV2/app-toc-assignment-viewerV2.component.mjs +327 -327
  31. package/esm2022/lib/_collection/_common/content-toc/app-toc-batch-assignments/app-toc-batch-assignments.component.mjs +297 -297
  32. package/esm2022/lib/_collection/_common/content-toc/app-toc-content/app-toc-content.component.mjs +304 -248
  33. package/esm2022/lib/_collection/_common/content-toc/app-toc-content-card-v2/app-toc-content-card-v2.component.mjs +1227 -1148
  34. package/esm2022/lib/_collection/_common/content-toc/app-toc-content-card-v2-skeleton/app-toc-content-card-v2-skeleton.component.mjs +16 -16
  35. package/esm2022/lib/_collection/_common/content-toc/app-toc-reference-notes/app-toc-reference-notes.component.mjs +43 -43
  36. package/esm2022/lib/_collection/_common/content-toc/app-toc-session-card-new/app-toc-session-card-new.component.mjs +133 -133
  37. package/esm2022/lib/_collection/_common/content-toc/app-toc-sessions-new/app-toc-sessions-new.component.mjs +66 -66
  38. package/esm2022/lib/_collection/_common/content-toc/app-toc-teachers-notes/app-toc-teachers-notes.component.mjs +278 -278
  39. package/esm2022/lib/_collection/_common/content-toc/content-services/handle-claim.service.mjs +21 -21
  40. package/esm2022/lib/_collection/_common/content-toc/content-services/review-component-data.service.mjs +21 -21
  41. package/esm2022/lib/_collection/_common/content-toc/content-toc.component.mjs +835 -847
  42. package/esm2022/lib/_collection/_common/content-toc/content-toc.module.mjs +224 -219
  43. package/esm2022/lib/_collection/_common/content-toc/karma-points/karma-points.component.mjs +276 -209
  44. package/esm2022/lib/_collection/_common/content-toc/karma-points/karma-points.module.mjs +26 -26
  45. package/esm2022/lib/_collection/_common/content-toc/pipes/replace-nbsp.pipe.mjs +19 -19
  46. package/esm2022/lib/_collection/_common/content-toc/pipes/truncate.pipe.mjs +23 -23
  47. package/esm2022/lib/_collection/_common/content-toc/reviews-content/reviews-content.component.mjs +113 -113
  48. package/esm2022/lib/_collection/_common/content-toc/samuhik-charcha-content/samuhik-charcha-content/samuhik-charcha-content.component.mjs +110 -110
  49. package/esm2022/lib/_collection/_common/display-content-type/display-content-type.component.mjs +26 -26
  50. package/esm2022/lib/_collection/_common/display-content-type/display-content-type.module.mjs +19 -19
  51. package/esm2022/lib/_collection/_common/display-content-type-icon/display-content-type-icon.component.mjs +67 -67
  52. package/esm2022/lib/_collection/_common/display-content-type-icon/display-content-type-icon.module.mjs +28 -28
  53. package/esm2022/lib/_collection/_common/mark-as-complete/mark-as-complete.component.mjs +77 -77
  54. package/esm2022/lib/_collection/_common/mark-as-complete/mark-as-complete.model.mjs +2 -2
  55. package/esm2022/lib/_collection/_common/mark-as-complete/mark-as-complete.module.mjs +61 -61
  56. package/esm2022/lib/_collection/_common/pipe-content-route/pipe-content-route.module.mjs +20 -20
  57. package/esm2022/lib/_collection/_common/pipe-content-route/pipe-content-route.pipe.mjs +67 -67
  58. package/esm2022/lib/_collection/_common/player-brief/player-brief.component.mjs +139 -139
  59. package/esm2022/lib/_collection/_common/player-brief/player-brief.module.mjs +71 -71
  60. package/esm2022/lib/_collection/_common/rating-summary/rating-summary.component.mjs +34 -34
  61. package/esm2022/lib/_collection/_common/rating-summary/rating-summary.module.mjs +56 -56
  62. package/esm2022/lib/_collection/_common/skeleton-loader/skeleton-loader.component.mjs +25 -25
  63. package/esm2022/lib/_collection/_common/skeleton-loader/skeleton-loader.module.mjs +37 -37
  64. package/esm2022/lib/_collection/_common/tips-for-learner/tips-for-learner-card/tips-for-learner-card.component.mjs +32 -32
  65. package/esm2022/lib/_collection/_common/tips-for-learner/tips-for-learner.module.mjs +30 -30
  66. package/esm2022/lib/_collection/_common/toc-kpi-values/toc-kpi-values.component.mjs +38 -38
  67. package/esm2022/lib/_collection/_common/toc-kpi-values/toc-kpi-values.module.mjs +51 -51
  68. package/esm2022/lib/_collection/_common/user-autocomplete/user-autocomplete.component.mjs +115 -115
  69. package/esm2022/lib/_collection/_common/user-autocomplete/user-autocomplete.model.mjs +12 -12
  70. package/esm2022/lib/_collection/_common/user-autocomplete/user-autocomplete.module.mjs +51 -51
  71. package/esm2022/lib/_collection/_common/user-autocomplete/user-autocomplete.service.mjs +61 -61
  72. package/esm2022/lib/_collection/_common/user-content-rating/user-content-rating.component.mjs +87 -87
  73. package/esm2022/lib/_collection/_common/user-content-rating/user-content-rating.module.mjs +36 -36
  74. package/esm2022/lib/_collection/_common/user-image/user-image.component.mjs +62 -62
  75. package/esm2022/lib/_collection/_common/user-image/user-image.module.mjs +24 -24
  76. package/esm2022/lib/_collection/btn-page-back/btn-page-back.component.mjs +192 -192
  77. package/esm2022/lib/_collection/btn-page-back/btn-page-back.module.mjs +44 -44
  78. package/esm2022/lib/_collection/btn-page-back/btn-page-back.service.mjs +99 -99
  79. package/esm2022/lib/_collection/card-rating-comment/card-rating-comment.component.mjs +58 -58
  80. package/esm2022/lib/_collection/card-rating-comment/card-rating-comment.module.mjs +67 -67
  81. package/esm2022/lib/_collection/sliders-dynamic/sliders-dynamic.component.mjs +115 -112
  82. package/esm2022/lib/_collection/sliders-dynamic/sliders-dynamic.model.mjs +2 -2
  83. package/esm2022/lib/_collection/sliders-dynamic/sliders-dynamic.module.mjs +69 -69
  84. package/esm2022/lib/_collection-api.mjs +57 -57
  85. package/esm2022/lib/_constants/widget-content.constants.mjs +19 -19
  86. package/esm2022/lib/_directives/tooltip.directive.mjs +68 -68
  87. package/esm2022/lib/_models/common.model.mjs +2 -2
  88. package/esm2022/lib/_models/error.model.mjs +2 -2
  89. package/esm2022/lib/_pipes/highlight.pipe.mjs +24 -24
  90. package/esm2022/lib/_services/rating.service.mjs +89 -89
  91. package/esm2022/lib/_services/samuhik-charcha.service.mjs +29 -29
  92. package/esm2022/lib/_services/viewer-route-util.mjs +103 -103
  93. package/esm2022/lib/_services/widget-content.model.mjs +254 -247
  94. package/esm2022/lib/_services/widget-content.service.mjs +594 -594
  95. package/esm2022/lib/_shared/translate-loader.factory.mjs +9 -9
  96. package/esm2022/lib/app-toc-lib.module.mjs +508 -499
  97. package/esm2022/lib/collection.config.mjs +161 -161
  98. package/esm2022/lib/components/app-toc-analytics-tiles/app-toc-analytics-tiles.component.mjs +37 -37
  99. package/esm2022/lib/components/app-toc-banner/app-toc-banner.component.mjs +1436 -1436
  100. package/esm2022/lib/components/app-toc-cios-home/app-toc-cios-home.component.mjs +522 -475
  101. package/esm2022/lib/components/app-toc-cios-home/consent-dialog.component.mjs +119 -119
  102. package/esm2022/lib/components/app-toc-cohorts/app-toc-cohorts.component.mjs +80 -80
  103. package/esm2022/lib/components/app-toc-content-card/app-toc-content-card.component.mjs +249 -249
  104. package/esm2022/lib/components/app-toc-dialog-intro-video/app-toc-dialog-intro-video.component.mjs +39 -39
  105. package/esm2022/lib/components/app-toc-discussion/app-toc-discussion.component.mjs +58 -58
  106. package/esm2022/lib/components/app-toc-home/app-toc-home.component.mjs +2230 -2229
  107. package/esm2022/lib/components/app-toc-home-v2/app-toc-home-v2.component.mjs +3017 -2907
  108. package/esm2022/lib/components/app-toc-overview/app-toc-overview.component.mjs +157 -157
  109. package/esm2022/lib/components/app-toc-session-card/app-toc-session-card.component.mjs +48 -48
  110. package/esm2022/lib/components/app-toc-sessions/app-toc-sessions.component.mjs +47 -47
  111. package/esm2022/lib/components/app-toc-single-page/app-toc-single-page.component.mjs +766 -766
  112. package/esm2022/lib/components/completion-survey-form/completion-survey-form.component.mjs +243 -243
  113. package/esm2022/lib/components/create-batch-dialog/create-batch-dialog.component.mjs +116 -116
  114. package/esm2022/lib/components/enroll-language-dialogue/enroll-language-dialogue.component.mjs +44 -44
  115. package/esm2022/lib/components/enroll-profile-form/enroll-profile-form.component.mjs +1854 -1838
  116. package/esm2022/lib/components/enroll-questionnaire/enroll-questionnaire.component.mjs +236 -236
  117. package/esm2022/lib/components/knowledge-artifact-details/knowledge-artifact-details.component.mjs +213 -213
  118. package/esm2022/lib/components/non-relevent-feedback-dialog/non-relevent-feedback-dialog.component.mjs +36 -36
  119. package/esm2022/lib/components/public-survey-form/public-survey-form.component.mjs +258 -256
  120. package/esm2022/lib/components/survey-form-question/survey-form-question.component.mjs +133 -133
  121. package/esm2022/lib/components/survey-form-section/survey-form-section.component.mjs +36 -36
  122. package/esm2022/lib/models/app-toc-analytics.model.mjs +2 -2
  123. package/esm2022/lib/models/app-toc.model.mjs +38 -38
  124. package/esm2022/lib/models/auto-complete.model.mjs +2 -2
  125. package/esm2022/lib/models/card-content.model.mjs +13 -13
  126. package/esm2022/lib/models/content-strip-with-tabs.model.mjs +2 -2
  127. package/esm2022/lib/models/discussion-forum.model.mjs +14 -14
  128. package/esm2022/lib/models/goal.model.mjs +2 -2
  129. package/esm2022/lib/models/meta-tag.model.mjs +8 -8
  130. package/esm2022/lib/models/playlist.model.mjs +2 -2
  131. package/esm2022/lib/models/profile-revamp.model.mjs +2 -2
  132. package/esm2022/lib/models/rating.model.mjs +2 -2
  133. package/esm2022/lib/models/user-profile.model.mjs +21 -21
  134. package/esm2022/lib/registration-toc-lib.config.mjs +14 -0
  135. package/esm2022/lib/resolvers/app-toc-cios-resolver.service.mjs +24 -24
  136. package/esm2022/lib/resolvers/app-toc-cios-user-enroll-resolver.service.mjs +24 -24
  137. package/esm2022/lib/resolvers/app-toc-content-read-resolver.service.mjs +60 -60
  138. package/esm2022/lib/resolvers/app-toc-ext-public-resolver.service.mjs +25 -25
  139. package/esm2022/lib/resolvers/app-toc-resolver.service.mjs +106 -106
  140. package/esm2022/lib/resolvers/config-resolver.service.mjs +25 -25
  141. package/esm2022/lib/resolvers/profile-resolver.service.mjs +25 -25
  142. package/esm2022/lib/resolvers/restricted-features-resolver.service.mjs +25 -25
  143. package/esm2022/lib/routes/app-toc-home/app-toc-home.component.mjs +51 -51
  144. package/esm2022/lib/routes/app-toc-home/app-toc-home.directive.mjs +16 -16
  145. package/esm2022/lib/routes/app-toc-home/app-toc-home.service.mjs +18 -18
  146. package/esm2022/lib/services/access-control.service.mjs +56 -56
  147. package/esm2022/lib/services/action.service.mjs +23 -23
  148. package/esm2022/lib/services/app-toc-v2.service.mjs +368 -313
  149. package/esm2022/lib/services/app-toc.service.mjs +1577 -1613
  150. package/esm2022/lib/services/certificate.service.mjs +114 -69
  151. package/esm2022/lib/services/discuss-utils.service.mjs +45 -58
  152. package/esm2022/lib/services/editor.service.mjs +34 -34
  153. package/esm2022/lib/services/load-check.service.mjs +21 -21
  154. package/esm2022/lib/services/loader.service.mjs +33 -33
  155. package/esm2022/lib/services/mobile-apps.service.mjs +67 -67
  156. package/esm2022/lib/services/netcore.service.mjs +126 -56
  157. package/esm2022/lib/services/nps-grid.service.mjs +43 -31
  158. package/esm2022/lib/services/otp.service.mjs +81 -43
  159. package/esm2022/lib/services/profile-v2.service.mjs +71 -43
  160. package/esm2022/lib/services/reset-ratings.service.mjs +19 -19
  161. package/esm2022/lib/services/resource-download-helper.service.mjs +64 -64
  162. package/esm2022/lib/services/root.service.mjs +106 -0
  163. package/esm2022/lib/services/timer.service.mjs +23 -23
  164. package/esm2022/lib/services/title-tag.service.mjs +71 -71
  165. package/esm2022/lib/services/user-profile.service.mjs +180 -55
  166. package/esm2022/lib/services/viewer-data.service.mjs +64 -64
  167. package/esm2022/lib/services/viewer-util.service.mjs +627 -590
  168. package/esm2022/lib/share-toc/share-toc/share-toc.component.mjs +291 -291
  169. package/esm2022/lib/share-toc/share-toc.module.mjs +119 -119
  170. package/esm2022/public-api.mjs +81 -71
  171. package/esm2022/sunbird-cb-toc.mjs +4 -4
  172. package/fesm2022/sunbird-cb-toc.mjs +27145 -24836
  173. package/fesm2022/sunbird-cb-toc.mjs.map +1 -1
  174. package/index.d.ts +5 -5
  175. package/lib/_collection/_common/ai-tutor/ai-tutor.component.d.ts +139 -0
  176. package/lib/_collection/_common/ai-tutor/socket.service.d.ts +19 -0
  177. package/lib/_collection/_common/attendance-card/attendance-card.component.d.ts +16 -16
  178. package/lib/_collection/_common/attendance-card/attendance-card.module.d.ts +31 -31
  179. package/lib/_collection/_common/attendance-helper/attendance-helper.component.d.ts +15 -15
  180. package/lib/_collection/_common/attendance-helper/attendance-helper.module.d.ts +20 -20
  181. package/lib/_collection/_common/avatar-photo/avatar-photo.component.d.ts +22 -22
  182. package/lib/_collection/_common/avatar-photo/avatar-photo.module.d.ts +15 -15
  183. package/lib/_collection/_common/card-competency/card-competency.component.d.ts +14 -0
  184. package/lib/_collection/_common/card-competency/card-competency.module.d.ts +8 -0
  185. package/lib/_collection/_common/card-content-v2/card-content-v2.model.d.ts +44 -0
  186. package/lib/_collection/_common/certificate-dialog/certificate-dialog.component.d.ts +31 -22
  187. package/lib/_collection/_common/certificate-dialog/certificate-dialog.module.d.ts +23 -22
  188. package/lib/_collection/_common/certificate-dialog/svg-to-pdf.component.d.ts +9 -9
  189. package/lib/_collection/_common/confirm-dialog/confirm-dialog.component.d.ts +11 -11
  190. package/lib/_collection/_common/confirm-dialog/confirm-dialog.module.d.ts +12 -12
  191. package/lib/_collection/_common/connection-hover-card/connection-hover-card.component.d.ts +18 -18
  192. package/lib/_collection/_common/connection-hover-card/connection-hover.module.d.ts +14 -14
  193. package/lib/_collection/_common/connection-hover-card/connection-hover.servive.d.ts +11 -11
  194. package/lib/_collection/_common/connection-name/connection-name.component.d.ts +17 -17
  195. package/lib/_collection/_common/connection-name/connection-name.module.d.ts +14 -14
  196. package/lib/_collection/_common/connection-name/profile-v2.model.d.ts +199 -199
  197. package/lib/_collection/_common/content-progress/content-progress.component.d.ts +16 -16
  198. package/lib/_collection/_common/content-progress/content-progress.module.d.ts +10 -10
  199. package/lib/_collection/_common/content-rating-v2-dialog/content-rating-v2-dialog.component.d.ts +38 -38
  200. package/lib/_collection/_common/content-rating-v2-dialog/content-rating-v2-dialog.module.d.ts +19 -19
  201. package/lib/_collection/_common/content-toc/ai-tutor-confirm-popup/ai-tutor-confirm-popup.component.d.ts +11 -11
  202. package/lib/_collection/_common/content-toc/app-toc-about/app-toc-about.component.d.ts +187 -183
  203. package/lib/_collection/_common/content-toc/app-toc-assignment-viewer/app-toc-assignment-viewer.component.d.ts +41 -41
  204. package/lib/_collection/_common/content-toc/app-toc-assignment-viewerV2/app-toc-assignment-viewerV2.component.d.ts +54 -54
  205. package/lib/_collection/_common/content-toc/app-toc-batch-assignments/app-toc-batch-assignments.component.d.ts +47 -47
  206. package/lib/_collection/_common/content-toc/app-toc-content/app-toc-content.component.d.ts +56 -49
  207. package/lib/_collection/_common/content-toc/app-toc-content-card-v2/app-toc-content-card-v2.component.d.ts +195 -171
  208. package/lib/_collection/_common/content-toc/app-toc-content-card-v2-skeleton/app-toc-content-card-v2-skeleton.component.d.ts +8 -8
  209. package/lib/_collection/_common/content-toc/app-toc-reference-notes/app-toc-reference-notes.component.d.ts +16 -16
  210. package/lib/_collection/_common/content-toc/app-toc-session-card-new/app-toc-session-card-new.component.d.ts +40 -40
  211. package/lib/_collection/_common/content-toc/app-toc-sessions-new/app-toc-sessions-new.component.d.ts +21 -21
  212. package/lib/_collection/_common/content-toc/app-toc-teachers-notes/app-toc-teachers-notes.component.d.ts +45 -45
  213. package/lib/_collection/_common/content-toc/content-services/handle-claim.service.d.ts +10 -10
  214. package/lib/_collection/_common/content-toc/content-services/review-component-data.service.d.ts +10 -10
  215. package/lib/_collection/_common/content-toc/content-toc.component.d.ts +131 -128
  216. package/lib/_collection/_common/content-toc/content-toc.module.d.ts +52 -51
  217. package/lib/_collection/_common/content-toc/karma-points/karma-points.component.d.ts +32 -29
  218. package/lib/_collection/_common/content-toc/karma-points/karma-points.module.d.ts +9 -9
  219. package/lib/_collection/_common/content-toc/pipes/replace-nbsp.pipe.d.ts +7 -7
  220. package/lib/_collection/_common/content-toc/pipes/truncate.pipe.d.ts +7 -7
  221. package/lib/_collection/_common/content-toc/reviews-content/reviews-content.component.d.ts +28 -28
  222. package/lib/_collection/_common/content-toc/samuhik-charcha-content/samuhik-charcha-content/samuhik-charcha-content.component.d.ts +24 -24
  223. package/lib/_collection/_common/display-content-type/display-content-type.component.d.ts +14 -14
  224. package/lib/_collection/_common/display-content-type/display-content-type.module.d.ts +9 -9
  225. package/lib/_collection/_common/display-content-type-icon/display-content-type-icon.component.d.ts +12 -12
  226. package/lib/_collection/_common/display-content-type-icon/display-content-type-icon.module.d.ts +10 -10
  227. package/lib/_collection/_common/mark-as-complete/mark-as-complete.component.d.ts +22 -22
  228. package/lib/_collection/_common/mark-as-complete/mark-as-complete.model.d.ts +8 -8
  229. package/lib/_collection/_common/mark-as-complete/mark-as-complete.module.d.ts +18 -18
  230. package/lib/_collection/_common/pipe-content-route/pipe-content-route.module.d.ts +8 -8
  231. package/lib/_collection/_common/pipe-content-route/pipe-content-route.pipe.d.ts +15 -15
  232. package/lib/_collection/_common/player-brief/player-brief.component.d.ts +35 -35
  233. package/lib/_collection/_common/player-brief/player-brief.module.d.ts +19 -19
  234. package/lib/_collection/_common/rating-summary/rating-summary.component.d.ts +14 -14
  235. package/lib/_collection/_common/rating-summary/rating-summary.module.d.ts +13 -13
  236. package/lib/_collection/_common/skeleton-loader/skeleton-loader.component.d.ts +11 -11
  237. package/lib/_collection/_common/skeleton-loader/skeleton-loader.module.d.ts +11 -11
  238. package/lib/_collection/_common/tips-for-learner/tips-for-learner-card/tips-for-learner-card.component.d.ts +15 -15
  239. package/lib/_collection/_common/tips-for-learner/tips-for-learner.module.d.ts +10 -10
  240. package/lib/_collection/_common/toc-kpi-values/toc-kpi-values.component.d.ts +16 -16
  241. package/lib/_collection/_common/toc-kpi-values/toc-kpi-values.module.d.ts +11 -11
  242. package/lib/_collection/_common/user-autocomplete/user-autocomplete.component.d.ts +34 -34
  243. package/lib/_collection/_common/user-autocomplete/user-autocomplete.model.d.ts +17 -17
  244. package/lib/_collection/_common/user-autocomplete/user-autocomplete.module.d.ts +15 -15
  245. package/lib/_collection/_common/user-autocomplete/user-autocomplete.service.d.ts +15 -15
  246. package/lib/_collection/_common/user-content-rating/user-content-rating.component.d.ts +21 -21
  247. package/lib/_collection/_common/user-content-rating/user-content-rating.module.d.ts +12 -12
  248. package/lib/_collection/_common/user-image/user-image.component.d.ts +21 -21
  249. package/lib/_collection/_common/user-image/user-image.module.d.ts +9 -9
  250. package/lib/_collection/btn-page-back/btn-page-back.component.d.ts +47 -47
  251. package/lib/_collection/btn-page-back/btn-page-back.module.d.ts +14 -14
  252. package/lib/_collection/btn-page-back/btn-page-back.service.d.ts +22 -22
  253. package/lib/_collection/card-rating-comment/card-rating-comment.component.d.ts +19 -19
  254. package/lib/_collection/card-rating-comment/card-rating-comment.module.d.ts +15 -15
  255. package/lib/_collection/sliders-dynamic/sliders-dynamic.component.d.ts +26 -25
  256. package/lib/_collection/sliders-dynamic/sliders-dynamic.model.d.ts +21 -21
  257. package/lib/_collection/sliders-dynamic/sliders-dynamic.module.d.ts +18 -18
  258. package/lib/_collection-api.d.ts +34 -34
  259. package/lib/_constants/widget-content.constants.d.ts +7 -7
  260. package/lib/_directives/tooltip.directive.d.ts +17 -17
  261. package/lib/_models/common.model.d.ts +3 -3
  262. package/lib/_models/error.model.d.ts +5 -5
  263. package/lib/_pipes/highlight.pipe.d.ts +10 -10
  264. package/lib/_services/rating.service.d.ts +18 -18
  265. package/lib/_services/samuhik-charcha.service.d.ts +13 -13
  266. package/lib/_services/viewer-route-util.d.ts +8 -8
  267. package/lib/_services/widget-content.model.d.ts +521 -515
  268. package/lib/_services/widget-content.service.d.ts +101 -101
  269. package/lib/_shared/translate-loader.factory.d.ts +7 -7
  270. package/lib/app-toc-lib.module.d.ts +89 -88
  271. package/lib/collection.config.d.ts +159 -159
  272. package/lib/components/app-toc-analytics-tiles/app-toc-analytics-tiles.component.d.ts +17 -17
  273. package/lib/components/app-toc-banner/app-toc-banner.component.d.ts +225 -225
  274. package/lib/components/app-toc-cios-home/app-toc-cios-home.component.d.ts +83 -78
  275. package/lib/components/app-toc-cios-home/consent-dialog.component.d.ts +22 -22
  276. package/lib/components/app-toc-cohorts/app-toc-cohorts.component.d.ts +31 -31
  277. package/lib/components/app-toc-content-card/app-toc-content-card.component.d.ts +47 -47
  278. package/lib/components/app-toc-dialog-intro-video/app-toc-dialog-intro-video.component.d.ts +14 -14
  279. package/lib/components/app-toc-discussion/app-toc-discussion.component.d.ts +21 -21
  280. package/lib/components/app-toc-home/app-toc-home.component.d.ts +315 -314
  281. package/lib/components/app-toc-home-v2/app-toc-home-v2.component.d.ts +418 -408
  282. package/lib/components/app-toc-overview/app-toc-overview.component.d.ts +47 -47
  283. package/lib/components/app-toc-session-card/app-toc-session-card.component.d.ts +22 -22
  284. package/lib/components/app-toc-sessions/app-toc-sessions.component.d.ts +14 -14
  285. package/lib/components/app-toc-single-page/app-toc-single-page.component.d.ts +149 -149
  286. package/lib/components/completion-survey-form/completion-survey-form.component.d.ts +42 -42
  287. package/lib/components/create-batch-dialog/create-batch-dialog.component.d.ts +27 -27
  288. package/lib/components/enroll-language-dialogue/enroll-language-dialogue.component.d.ts +15 -15
  289. package/lib/components/enroll-profile-form/enroll-profile-form.component.d.ts +197 -195
  290. package/lib/components/enroll-questionnaire/enroll-questionnaire.component.d.ts +44 -44
  291. package/lib/components/knowledge-artifact-details/knowledge-artifact-details.component.d.ts +54 -54
  292. package/lib/components/non-relevent-feedback-dialog/non-relevent-feedback-dialog.component.d.ts +18 -18
  293. package/lib/components/public-survey-form/public-survey-form.component.d.ts +44 -43
  294. package/lib/components/survey-form-question/survey-form-question.component.d.ts +20 -20
  295. package/lib/components/survey-form-section/survey-form-section.component.d.ts +13 -13
  296. package/lib/models/app-toc-analytics.model.d.ts +152 -152
  297. package/lib/models/app-toc.model.d.ts +84 -84
  298. package/lib/models/auto-complete.model.d.ts +27 -27
  299. package/lib/models/card-content.model.d.ts +19 -19
  300. package/lib/models/content-strip-with-tabs.model.d.ts +44 -44
  301. package/lib/models/discussion-forum.model.d.ts +40 -40
  302. package/lib/models/goal.model.d.ts +22 -22
  303. package/lib/models/meta-tag.model.d.ts +6 -6
  304. package/lib/models/playlist.model.d.ts +23 -23
  305. package/lib/models/profile-revamp.model.d.ts +14 -14
  306. package/lib/models/rating.model.d.ts +17 -17
  307. package/lib/models/user-profile.model.d.ts +124 -37
  308. package/lib/registration-toc-lib.config.d.ts +4 -0
  309. package/lib/resolvers/app-toc-cios-resolver.service.d.ts +12 -12
  310. package/lib/resolvers/app-toc-cios-user-enroll-resolver.service.d.ts +12 -12
  311. package/lib/resolvers/app-toc-content-read-resolver.service.d.ts +16 -16
  312. package/lib/resolvers/app-toc-ext-public-resolver.service.d.ts +12 -12
  313. package/lib/resolvers/app-toc-resolver.service.d.ts +16 -16
  314. package/lib/resolvers/config-resolver.service.d.ts +11 -11
  315. package/lib/resolvers/profile-resolver.service.d.ts +11 -11
  316. package/lib/resolvers/restricted-features-resolver.service.d.ts +11 -11
  317. package/lib/routes/app-toc-home/app-toc-home.component.d.ts +19 -19
  318. package/lib/routes/app-toc-home/app-toc-home.directive.d.ts +8 -8
  319. package/lib/routes/app-toc-home/app-toc-home.service.d.ts +8 -8
  320. package/lib/services/access-control.service.d.ts +29 -29
  321. package/lib/services/action.service.d.ts +9 -9
  322. package/lib/services/app-toc-v2.service.d.ts +17 -16
  323. package/lib/services/app-toc.service.d.ts +190 -235
  324. package/lib/services/certificate.service.d.ts +41 -42
  325. package/lib/services/discuss-utils.service.d.ts +11 -33
  326. package/lib/services/editor.service.d.ts +17 -17
  327. package/lib/services/load-check.service.d.ts +8 -8
  328. package/lib/services/loader.service.d.ts +16 -16
  329. package/lib/services/mobile-apps.service.d.ts +38 -38
  330. package/lib/services/netcore.service.d.ts +21 -33
  331. package/lib/services/nps-grid.service.d.ts +16 -15
  332. package/lib/services/otp.service.d.ts +15 -20
  333. package/lib/services/profile-v2.service.d.ts +17 -20
  334. package/lib/services/reset-ratings.service.d.ts +8 -8
  335. package/lib/services/resource-download-helper.service.d.ts +29 -29
  336. package/lib/services/root.service.d.ts +26 -0
  337. package/lib/services/timer.service.d.ts +9 -9
  338. package/lib/services/title-tag.service.d.ts +21 -21
  339. package/lib/services/user-profile.service.d.ts +44 -24
  340. package/lib/services/viewer-data.service.d.ts +62 -58
  341. package/lib/services/viewer-util.service.d.ts +76 -76
  342. package/lib/share-toc/share-toc/share-toc.component.d.ts +56 -56
  343. package/lib/share-toc/share-toc.module.d.ts +32 -32
  344. package/package.json +3 -3
  345. package/public-api.d.ts +65 -56
  346. package/sunbird-cb-toc-0.0.10-mauritius.tgz +0 -0
@@ -1,1148 +1,1227 @@
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLXRvYy1jb250ZW50LWNhcmQtdjIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicmFyeS9zdW5iaXJkLWNiL3RvYy9zcmMvbGliL19jb2xsZWN0aW9uL19jb21tb24vY29udGVudC10b2MvYXBwLXRvYy1jb250ZW50LWNhcmQtdjIvYXBwLXRvYy1jb250ZW50LWNhcmQtdjIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicmFyeS9zdW5iaXJkLWNiL3RvYy9zcmMvbGliL19jb2xsZWN0aW9uL19jb21tb24vY29udGVudC10b2MvYXBwLXRvYy1jb250ZW50LWNhcmQtdjIvYXBwLXRvYy1jb250ZW50LWNhcmQtdjIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQW9DLE1BQU0sZUFBZSxDQUFBO0FBQ2xGLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQTtBQUN0RSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQTtBQUU5RSxPQUFPLEVBQWdCLFFBQVEsRUFBeUIsTUFBTSxzQkFBc0IsQ0FBQTtBQUNwRixPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSx1REFBdUQsQ0FBQTtBQUVsRyxPQUFPLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUE7QUFDekUsbUJBQW1CO0FBQ25CLE9BQU8sQ0FBQyxNQUFNLFFBQVEsQ0FBQTtBQUN0QixPQUFPLE1BQU0sTUFBTSxRQUFRLENBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUF3QjNCLE1BQU0sT0FBTyw0QkFBNEI7SUEyRHZDLFlBQ1UsTUFBb0IsRUFDcEIsTUFBaUIsRUFDakIsUUFBbUIsRUFDbkIsa0JBQXNDLEVBQ3RDLFNBQXdCLEVBQ3hCLGNBQXNDLEVBQ3RDLHlCQUF3RCxFQUN4RCxTQUFnQyxFQUNoQyxRQUFxQjtRQVJyQixXQUFNLEdBQU4sTUFBTSxDQUFjO1FBQ3BCLFdBQU0sR0FBTixNQUFNLENBQVc7UUFDakIsYUFBUSxHQUFSLFFBQVEsQ0FBVztRQUNuQix1QkFBa0IsR0FBbEIsa0JBQWtCLENBQW9CO1FBQ3RDLGNBQVMsR0FBVCxTQUFTLENBQWU7UUFDeEIsbUJBQWMsR0FBZCxjQUFjLENBQXdCO1FBQ3RDLDhCQUF5QixHQUF6Qix5QkFBeUIsQ0FBK0I7UUFDeEQsY0FBUyxHQUFULFNBQVMsQ0FBdUI7UUFDaEMsYUFBUSxHQUFSLFFBQVEsQ0FBYTtRQW5FdEIsWUFBTyxHQUE4QixJQUFJLENBQUE7UUFDekMsY0FBUyxHQUFHLEtBQUssQ0FBQTtRQUdqQixlQUFVLEdBQUcsS0FBSyxDQUFBO1FBRWxCLGtCQUFhLEdBQVcsS0FBSyxDQUFBO1FBRzdCLGlCQUFZLEdBQUcsSUFBSSxDQUFBO1FBQ25CLHFCQUFnQixHQUFRLEVBQUUsQ0FBQTtRQUMxQixjQUFTLEdBQWtELElBQUksQ0FBQTtRQUMvRCxvQkFBZSxHQUFHLEtBQUssQ0FBQTtRQUN2Qix3QkFBbUIsR0FBOEIsSUFBSSxDQUFBO1FBQ3JELGFBQVEsR0FBOEIsSUFBSSxDQUFBO1FBQzFDLDBCQUFxQixHQUFHLEtBQUssQ0FBQSxDQUFDLG9EQUFvRDtRQUMzRix3QkFBbUIsR0FBRyxLQUFLLENBQUE7UUFDM0IsK0JBQTBCLEdBQUcsS0FBSyxDQUFBO1FBQ2xDLHFCQUFnQixHQUFHLFNBQVMsQ0FBQyxvQkFBb0IsQ0FBQTtRQUNqRCxxQkFBZ0IsR0FBMkI7WUFDekMsVUFBVSxFQUFFLENBQUM7WUFDYixTQUFTLEVBQUUsQ0FBQztZQUNaLE1BQU0sRUFBRSxDQUFDO1lBQ1QsT0FBTyxFQUFFLENBQUM7WUFDVixnQkFBZ0IsRUFBRSxDQUFDO1lBQ25CLGNBQWMsRUFBRSxDQUFDO1lBQ2pCLEtBQUssRUFBRSxDQUFDO1lBQ1IsR0FBRyxFQUFFLENBQUM7WUFDTixNQUFNLEVBQUUsQ0FBQztZQUNULE9BQU8sRUFBRSxDQUFDO1lBQ1YsWUFBWSxFQUFFLENBQUM7WUFDZixJQUFJLEVBQUUsQ0FBQztZQUNQLEtBQUssRUFBRSxDQUFDO1lBQ1IsU0FBUyxFQUFFLENBQUM7WUFDWixPQUFPLEVBQUUsQ0FBQztZQUNWLE9BQU8sRUFBRSxDQUFDO1lBQ1Ysa0JBQWtCLEVBQUUsQ0FBQztZQUNyQixjQUFjLEVBQUUsQ0FBQztTQUNsQixDQUFBO1FBQ0QscUJBQWdCLEdBQUcsRUFBRSxDQUFBO1FBQ3JCLGlCQUFZLEdBQUcsS0FBSyxDQUFBO1FBQ3BCLG9CQUFlLEdBQUcsU0FBUyxDQUFDLGdCQUFnQixDQUFBO1FBQzVDLDJCQUFzQixHQUF3QixJQUFJLENBQUE7UUFDbEQsdUJBQWtCLEdBQVksS0FBSyxDQUFBO1FBQ25DLDBEQUEwRDtRQUNsRCx3QkFBbUIsR0FBWSxLQUFLLENBQUE7UUFDcEMsb0JBQWUsR0FBWSxLQUFLLENBQUE7UUFDaEMsc0JBQWlCLEdBQVksS0FBSyxDQUFBO1FBQ2xDLHVCQUFrQixHQUFZLEtBQUssQ0FBQTtRQUNuQyw2QkFBd0IsR0FBWSxLQUFLLENBQUE7UUFDekMsbUNBQThCLEdBQVksS0FBSyxDQUFBO1FBQy9DLDZCQUF3QixHQUFZLElBQUksQ0FBQTtRQUN4QyxrQ0FBNkIsR0FBWSxLQUFLLENBQUE7UUFDOUMsaUNBQTRCLEdBQVksS0FBSyxDQUFBO1FBQzdDLHVDQUFrQyxHQUFZLEtBQUssQ0FBQTtRQUNuRCx3QkFBbUIsR0FBeUQsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLFdBQVcsRUFBRSxFQUFFLEVBQUUsQ0FBQTtRQUN4RyxzQkFBaUIsR0FBWSxLQUFLLENBQUE7SUFZdEMsQ0FBQztJQUVMLFFBQVE7UUFDTixJQUFJLENBQUMsa0NBQWtDLEVBQUUsQ0FBQTtRQUN6QyxJQUFJLENBQUMsNEJBQTRCLEVBQUUsQ0FBQTtRQUNuQyxzQ0FBc0M7UUFDdEMsd0VBQXdFO1FBQ3hFLE1BQU07UUFDTixJQUFJO1FBQ0osSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFBO0lBQ3ZCLENBQUM7SUFFRDs7O09BR0c7SUFDSyw0QkFBNEI7UUFDbEMsSUFBSSxDQUFDLDBCQUEwQixFQUFFLENBQUE7SUFDbkMsQ0FBQztJQUVEOztPQUVHO0lBQ0ssMEJBQTBCO1FBQ2hDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ2pCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxLQUFLLENBQUE7WUFDOUIsT0FBTTtTQUNQO1FBRUQsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUE7UUFDekMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixJQUFJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsQ0FBQTtRQUUxRSx3REFBd0Q7UUFDeEQsSUFBSSxRQUFRLEVBQUU7WUFDWixJQUFJLENBQUMsbUJBQW1CLEdBQUcsUUFBUSxDQUFDLFlBQVksS0FBSyxTQUFTLENBQUMsQ0FBQztnQkFDOUQsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEtBQUssU0FBUyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUE7WUFDbkYsSUFBSSxDQUFDLGVBQWUsR0FBRyxRQUFRLENBQUMsUUFBUSxLQUFLLFNBQVMsQ0FBQyxDQUFDO2dCQUN0RCxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsS0FBSyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFBO1lBQ3hGLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxRQUFRLENBQUMsVUFBVSxLQUFLLFNBQVMsQ0FBQyxDQUFDO2dCQUMxRCxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQTtZQUNoRCxJQUFJLENBQUMsa0JBQWtCLEdBQUcsUUFBUSxDQUFDLFdBQVcsS0FBSyxTQUFTLENBQUMsQ0FBQztnQkFDNUQsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUE7WUFDbEQsSUFBSSxDQUFDLHdCQUF3QixHQUFHLFFBQVEsQ0FBQyxnQkFBZ0IsS0FBSyxTQUFTLENBQUMsQ0FBQztnQkFDdkUsUUFBUSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQTtZQUM3RCxJQUFJLENBQUMsOEJBQThCLEdBQUcsUUFBUSxDQUFDLHVCQUF1QixLQUFLLFNBQVMsQ0FBQyxDQUFDO2dCQUNwRixRQUFRLENBQUMsdUJBQXVCLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyw4QkFBOEIsRUFBRSxDQUFBO1NBQzNFO2FBQU07WUFDTCwwREFBMEQ7WUFDMUQsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxLQUFLLFNBQVMsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFBO1lBQ3BGLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQTtZQUN6RixJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUE7WUFDakQsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFBO1lBQ25ELElBQUksQ0FBQyx3QkFBd0IsR0FBRyxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQTtZQUMvRCxJQUFJLENBQUMsOEJBQThCLEdBQUcsSUFBSSxDQUFDLDhCQUE4QixFQUFFLENBQUE7U0FDNUU7UUFFRCxJQUFJLENBQUMsNkJBQTZCLEdBQUcsSUFBSSxDQUFDLDZCQUE2QixFQUFFLENBQUE7UUFDekUsSUFBSSxDQUFDLHdCQUF3QixHQUFHLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFBO1FBQy9ELElBQUksQ0FBQyw0QkFBNEIsR0FBRyxJQUFJLENBQUMsNEJBQTRCLEVBQUUsQ0FBQTtRQUN2RSxJQUFJLENBQUMsa0NBQWtDLEdBQUcsSUFBSSxDQUFDLGtDQUFrQyxFQUFFLENBQUE7UUFDbkYsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFBO1FBQ3JELElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUE7SUFDL0IsQ0FBQztJQUVPLGlCQUFpQjtRQUN2QixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU87WUFBRSxPQUFPLEtBQUssQ0FBQTtRQUMvQixPQUFPLENBQ0wsSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLFFBQVE7WUFDcEUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLGlCQUFpQjtZQUM3RSxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsS0FBSyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsZ0JBQWdCO1lBQzVFLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxLQUFLLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxlQUFlLENBQzVFLENBQUE7SUFDSCxDQUFDO0lBRU8sa0JBQWtCO1FBQ3hCLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU8sS0FBSyxDQUFBO1FBQy9CLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBeUIsQ0FBQTtRQUN6RCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGNBQXdCLENBQUE7UUFDdkQsT0FBTyxVQUFVLEtBQUssV0FBVyxJQUFJLFNBQVMsS0FBSyxXQUFXLENBQUE7SUFDaEUsQ0FBQztJQUVPLDZCQUE2QjtRQUNuQyxJQUFJLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLGdCQUFnQixJQUFJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQzlHLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFBO1lBQzdELE9BQU8sVUFBVSxJQUFJLFVBQVUsQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLGVBQWU7Z0JBQzVGLFVBQVUsQ0FBQyxrQkFBa0IsSUFBSSxDQUFDO2dCQUNsQyxVQUFVLENBQUMsa0JBQWtCLEtBQUssU0FBUyxDQUFDLG1CQUFtQixDQUFDLHNCQUFzQixDQUFBO1NBQ3pGO1FBQ0QsT0FBTyxLQUFLLENBQUE7SUFDZCxDQUFDO0lBRU8sd0JBQXdCO1FBQzlCLElBQUksSUFBSSxDQUFDLDZCQUE2QixFQUFFO1lBQ3RDLElBQUksSUFBSSxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsZ0JBQWdCLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUU7Z0JBQzlHLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFBO2dCQUM3RCxJQUFJLGtCQUFrQixHQUFVLEVBQUUsQ0FBQTtnQkFDbEMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFTLEVBQUUsRUFBRTtvQkFDekMsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxFQUFFO3dCQUN4RCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUE7d0JBQzdDLElBQUksU0FBUyxJQUFJLFNBQVMsQ0FBQyxnQkFBZ0IsS0FBSyxDQUFDLEVBQUU7NEJBQ2pELGtCQUFrQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQTt5QkFDbkM7cUJBQ0Y7Z0JBQ0gsQ0FBQyxDQUFDLENBQUE7Z0JBQ0YsT0FBTyxrQkFBa0IsQ0FBQyxNQUFNLElBQUksVUFBVSxDQUFDLGNBQWMsR0FBRyxDQUFDLENBQUE7YUFDbEU7WUFDRCxPQUFPLEtBQUssQ0FBQTtTQUNiO1FBQ0QsT0FBTyxJQUFJLENBQUE7SUFDYixDQUFDO0lBRU8sbUJBQW1CO1FBQ3pCLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNoQixJQUFJLFFBQVEsR0FBUSxFQUFFLENBQUE7WUFDdEIsSUFBSSxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxLQUFLLDBCQUEwQjtnQkFDNUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEtBQUssMkNBQTJDLEVBQ3JFO2dCQUNBLFFBQVEsR0FBRyxxQ0FBcUMsQ0FBQTtnQkFDaEQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEdBQUcsU0FBUyxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQTthQUM5RDtpQkFBTTtnQkFDTCxRQUFRLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUE7YUFDakM7WUFDRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUE7WUFDM0csT0FBTyxvQkFBb0IsQ0FDekIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQ3ZCLFFBQVEsRUFDUixJQUFJLENBQUMsbUJBQW1CLEVBQUUsVUFBVSxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQ25ELElBQUksQ0FBQyxtQkFBbUIsRUFBRSxXQUFXLElBQUksSUFBSSxDQUFDLGVBQWUsRUFDN0QsSUFBSSxDQUFDLFVBQVUsRUFDZixJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFDNUIsSUFBSSxDQUFDLE9BQU8sRUFDWixJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksSUFBSSxJQUFJLENBQUMsbUJBQW1CLEVBQUUsSUFBSSxFQUNwRCxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUNuRCxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUN4RCxDQUFBO1NBQ0Y7UUFDRCxPQUFPLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxXQUFXLEVBQUUsRUFBRSxFQUFFLENBQUE7SUFDckMsQ0FBQztJQUVPLHdCQUF3QjtRQUM5Qiw0REFBNEQ7UUFDNUQsSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsSUFBSSxJQUFJLENBQUMsbUJBQW1CLENBQUMsY0FBYyxLQUFLLGtCQUFrQixFQUFFO1lBQy9GLE9BQU8sS0FBSyxDQUFBO1NBQ2I7UUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNqQixPQUFPLEtBQUssQ0FBQTtTQUNiO1FBRUQsMENBQTBDO1FBQzFDLElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsRUFBRTtZQUMxRCxPQUFPLEtBQUssQ0FBQTtTQUNiO1FBRUQscUZBQXFGO1FBQ3JGLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQTtRQUN4RixPQUFPLENBQUMsR0FBRyxDQUFDLGdDQUFnQyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsS0FBSyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksSUFBSSxFQUFFO1lBQzdGLFFBQVE7WUFDUixnQkFBZ0IsRUFBRSxRQUFRLEVBQUUsZ0JBQWdCO1lBQzVDLGVBQWUsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVE7U0FDdkMsQ0FBQyxDQUFBO1FBRUYsSUFBSSxRQUFRLElBQUksUUFBUSxDQUFDLGdCQUFnQixLQUFLLFNBQVMsRUFBRTtZQUN2RCxPQUFPLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQTtTQUNqQztRQUVELHdFQUF3RTtRQUN4RSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxLQUFLLEtBQUssRUFBRTtZQUNuQyxPQUFPLEtBQUssQ0FBQTtTQUNiO1FBRUQsMEVBQTBFO1FBQzFFLHlFQUF5RTtRQUN6RSxPQUFPLElBQUksQ0FBQTtJQUNiLENBQUM7SUFFTyw4QkFBOEI7UUFDcEMsSUFBSSxJQUFJLENBQUMscUJBQXFCLEVBQUU7WUFDOUIsT0FBTyxJQUFJLENBQUE7U0FDWjtRQUVELElBQUksQ0FBQyxJQUFJLENBQUMsbUJBQW1CLElBQUksSUFBSSxDQUFDLG1CQUFtQixDQUFDLGNBQWMsS0FBSyxrQkFBa0IsRUFBRTtZQUMvRixPQUFPLEtBQUssQ0FBQTtTQUNiO1FBRUQsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUU7WUFDM0MsT0FBTyxLQUFLLENBQUE7U0FDYjtRQUVELHVDQUF1QztRQUN2QyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQTtRQUMvRCxJQUFJLFFBQVEsSUFBSSxRQUFRLENBQUMsdUJBQXVCLEtBQUssU0FBUyxFQUFFO1lBQzlELE9BQU8sUUFBUSxDQUFDLHVCQUF1QixDQUFBO1NBQ3hDO1FBRUQsMEVBQTBFO1FBQzFFLElBQUksZUFBZSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFBO1FBQ3pDLE1BQU0sUUFBUSxHQUFHLENBQUMsQ0FBQTtRQUNsQixJQUFJLEtBQUssR0FBRyxDQUFDLENBQUE7UUFFYixPQUFPLGVBQWUsSUFBSSxLQUFLLEdBQUcsUUFBUSxFQUFFO1lBQzFDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxlQUFlLENBQUMsQ0FBQTtZQUN6RCxJQUFJLFVBQVUsRUFBRTtnQkFDZCxJQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsSUFBSSxVQUFVLENBQUMsZUFBZSxLQUFLLFdBQVcsSUFBSSxVQUFVLENBQUMsY0FBYyxLQUFLLFdBQVcsQ0FBQztvQkFDbkgsQ0FBQyxVQUFVLENBQUMsZ0JBQWdCLElBQUksVUFBVSxDQUFDLFFBQVEsQ0FBQyxFQUFFO29CQUN4RCxPQUFPLElBQUksQ0FBQTtpQkFDWjtnQkFDRCxlQUFlLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQTthQUNwQztpQkFBTTtnQkFDTCxNQUFLO2FBQ047WUFDRCxLQUFLLEVBQUUsQ0FBQTtTQUNSO1FBQ0QsT0FBTyxLQUFLLENBQUE7SUFDZCxDQUFDO0lBRUQ7O09BRUc7SUFDSyw0QkFBNEI7UUFDbEMsSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsSUFBSSxJQUFJLENBQUMsbUJBQW1CLENBQUMsY0FBYyxLQUFLLGtCQUFrQixFQUFFO1lBQy9GLE9BQU8sS0FBSyxDQUFBO1NBQ2I7UUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtZQUMzQyxPQUFPLEtBQUssQ0FBQTtTQUNiO1FBRUQsaUNBQWlDO1FBQ2pDLE1BQU0sWUFBWSxHQUNoQixJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsS0FBSyxtQkFBbUI7WUFDcEQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjLEtBQUssbUJBQW1CO1lBQ25ELENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUE7UUFFL0UsSUFBSSxDQUFDLFlBQVksRUFBRTtZQUNqQixPQUFPLEtBQUssQ0FBQTtTQUNiO1FBRUQsZ0hBQWdIO1FBQ2hILElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDckUsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUE7WUFFN0Qsd0NBQXdDO1lBQ3hDLElBQUksVUFBVSxDQUFDLFdBQVcsSUFBSSxVQUFVLENBQUMsZUFBZSxLQUFLLFdBQVcsSUFBSSxVQUFVLENBQUMsY0FBYyxLQUFLLFdBQVcsRUFBRTtnQkFDckgsT0FBTyxJQUFJLENBQUE7YUFDWjtZQUVELHlGQUF5RjtZQUN6RixJQUFJLFVBQVUsQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFBRTtnQkFDakUsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQTtnQkFDaEUsT0FBTyxlQUFlLENBQUMsV0FBVyxJQUFJLGVBQWUsQ0FBQyxlQUFlLEtBQUssV0FBVyxJQUFJLGVBQWUsQ0FBQyxjQUFjLEtBQUssV0FBVyxDQUFBO2FBQ3hJO1NBQ0Y7UUFFRCxPQUFPLEtBQUssQ0FBQTtJQUNkLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSyxrQ0FBa0M7UUFDeEMsOENBQThDO1FBQzlDLElBQUksQ0FBQyxJQUFJLENBQUMsNEJBQTRCLElBQUksQ0FBQyxJQUFJLENBQUMsNEJBQTRCLEVBQUUsRUFBRTtZQUM5RSxPQUFPLEtBQUssQ0FBQTtTQUNiO1FBRUQsOERBQThEO1FBQzlELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxVQUFVLElBQUksRUFBRSxDQUFDLENBQUE7UUFDL0YsSUFBSSxRQUFRLElBQUksUUFBUSxDQUFDLGtCQUFrQixLQUFLLFNBQVMsRUFBRTtZQUN6RCxPQUFPLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQTtTQUNuQztRQUVELG1DQUFtQztRQUNuQyxJQUFJLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLGdCQUFnQixLQUFLLENBQUM7WUFDcEQsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLG9CQUFvQixJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsb0JBQW9CLElBQUksR0FBRyxDQUFDLENBQUMsRUFBRTtZQUNwRixPQUFPLEtBQUssQ0FBQTtTQUNiO1FBRUQseURBQXlEO1FBQ3pELElBQUksV0FBK0IsQ0FBQTtRQUNuQyxJQUFJLFNBQWMsQ0FBQTtRQUVsQixzQ0FBc0M7UUFDdEMsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLE1BQU0sSUFBSSxJQUFJLENBQUMsZ0JBQWdCLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDL0YsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUE7WUFDN0QsSUFBSSxVQUFVLENBQUMsV0FBVyxJQUFJLFVBQVUsQ0FBQyxlQUFlLEtBQUssV0FBVyxJQUFJLFVBQVUsQ0FBQyxjQUFjLEtBQUssV0FBVyxFQUFFO2dCQUNySCxXQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUE7Z0JBQ2pDLFNBQVMsR0FBRyxVQUFVLENBQUE7YUFDdkI7aUJBQU0sSUFBSSxVQUFVLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEVBQUU7Z0JBQ3hFLG9DQUFvQztnQkFDcEMsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQTtnQkFDaEUsSUFBSSxlQUFlLENBQUMsV0FBVyxJQUFJLGVBQWUsQ0FBQyxlQUFlLEtBQUssV0FBVyxJQUFJLGVBQWUsQ0FBQyxjQUFjLEtBQUssV0FBVyxFQUFFO29CQUNwSSxXQUFXLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQTtvQkFDL0IsU0FBUyxHQUFHLGVBQWUsQ0FBQTtpQkFDNUI7YUFDRjtTQUNGO1FBRUQsSUFBSSxDQUFDLFdBQVcsSUFBSSxDQUFDLFNBQVMsRUFBRTtZQUM5QixPQUFPLEtBQUssQ0FBQTtTQUNiO1FBRUQseUVBQXlFO1FBQ3pFLG1DQUFtQztRQUNuQyxJQUFJLFNBQVMsQ0FBQyxnQkFBZ0IsSUFBSSxTQUFTLENBQUMsUUFBUSxFQUFFO1lBQ3BELE9BQU8sS0FBSyxDQUFBO1NBQ2I7UUFFRCwrREFBK0Q7UUFDL0QsSUFBSSxjQUFjLEdBQUcsQ0FBQyxDQUFBO1FBQ3RCLElBQUksdUJBQXVCLEdBQUcsQ0FBQyxDQUFBO1FBRS9CLDJEQUEyRDtRQUMzRCxLQUFLLE1BQU0sR0FBRyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEVBQUU7WUFDcEQsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxDQUFBO1lBRXZDLHVFQUF1RTtZQUN2RSw4REFBOEQ7WUFDOUQsSUFBSSxzQkFBc0IsR0FBRyxLQUFLLENBQUE7WUFDbEMsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLFdBQVcsRUFBRTtnQkFDL0Isc0JBQXNCLEdBQUcsSUFBSSxDQUFBO2FBQzlCO2lCQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFO2dCQUM1RCxtREFBbUQ7Z0JBQ25ELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUE7Z0JBQ3JELElBQUksVUFBVSxDQUFDLE1BQU0sS0FBSyxXQUFXLElBQUksVUFBVSxDQUFDLGVBQWUsS0FBSyxRQUFRLEVBQUU7b0JBQ2hGLHNCQUFzQixHQUFHLElBQUksQ0FBQTtpQkFDOUI7YUFDRjtZQUVELElBQUksQ0FBQyxzQkFBc0I7Z0JBQUUsU0FBUTtZQUVyQyxvRUFBb0U7WUFDcEUsTUFBTSxnQkFBZ0IsR0FDcEIsSUFBSSxDQUFDLGVBQWUsS0FBSyxtQkFBbUI7Z0JBQzVDLElBQUksQ0FBQyxlQUFlLEtBQUssa0JBQWtCO2dCQUMzQyxJQUFJLENBQUMsZUFBZSxLQUFLLHVCQUF1QjtnQkFDaEQsSUFBSSxDQUFDLGNBQWMsS0FBSyxtQkFBbUI7Z0JBQzNDLElBQUksQ0FBQyxRQUFRLEtBQUsscUNBQXFDO2dCQUN2RCxJQUFJLENBQUMsUUFBUSxLQUFLLGtCQUFrQjtnQkFDcEMsQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUE7WUFDL0QsSUFBSSxnQkFBZ0I7Z0JBQUUsU0FBUTtZQUU5Qix3RUFBd0U7WUFDeEUsdUVBQXVFO1lBQ3ZFLElBQUksSUFBSSxDQUFDLFdBQVcsS0FBSyxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxLQUFLLFFBQVEsSUFBSSxJQUFJLENBQUMsV0FBVyxLQUFLLElBQUksQ0FBQyxFQUFFO2dCQUNsRyxxRUFBcUU7Z0JBQ3JFLGNBQWMsRUFBRSxDQUFBO2dCQUNoQixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQztvQkFDakQsSUFBSSxDQUFDLG9CQUFvQixJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsUUFBUSxJQUFJLEdBQUcsQ0FBQTtnQkFDM0UsSUFBSSxXQUFXLEVBQUU7b0JBQ2YsdUJBQXVCLEVBQUUsQ0FBQTtpQkFDMUI7YUFDRjtTQUNGO1FBRUQsMERBQTBEO1FBQzFELElBQUksY0FBYyxLQUFLLENBQUMsRUFBRTtZQUN4QixPQUFPLEtBQUssQ0FBQTtTQUNiO1FBRUQsMkRBQTJEO1FBQzNELE1BQU0sb0JBQW9CLEdBQUcsdUJBQXVCLElBQUksY0FBYyxDQUFBO1FBQ3RFLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQTtJQUM5QixDQUFDO0lBRUQsNkNBQTZDO0lBQzdDLGNBQWM7UUFDWixJQUFJLENBQUMsc0JBQXNCLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsQ0FBQyxLQUFjLEVBQUUsRUFBRTtZQUN6RixJQUFJLEtBQUssRUFBRTtnQkFDVCxVQUFVLENBQUMsR0FBRyxFQUFFO29CQUNkLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQTtnQkFDbkIsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFBO2FBQ1I7UUFDSCxDQUFDLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFDRCwwREFBMEQ7SUFDMUQsY0FBYztRQUNaLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUN6QyxDQUFDO0lBRUQsV0FBVyxDQUFDLE9BQXNCO1FBQ2hDLElBQUksb0JBQW9CLEdBQUcsS0FBSyxDQUFBO1FBRWhDLEtBQUssTUFBTSxRQUFRLElBQUksT0FBTyxFQUFFO1lBQzlCLElBQUksUUFBUSxLQUFLLFdBQVcsRUFBRTtnQkFDNUIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFBO2FBQ25DO1lBQ0QsSUFBSSxRQUFRLEtBQUssU0FBUyxJQUFJLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRTtnQkFDaEQsSUFBSSxZQUFZLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLFlBQVksQ0FBQTtnQkFDbEQsSUFBSSxhQUFhLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLGFBQWEsQ0FBQTtnQkFDcEQsSUFBSSxZQUFZLElBQUksYUFBYSxFQUFFO29CQUNqQyxNQUFNLEtBQUssR0FBRyxDQUFDLEVBQU8sRUFBRSxFQUFPLEVBQUUsRUFBRSxDQUNqQyxFQUFFLENBQUMsSUFBSSxLQUFLLEVBQUUsQ0FBQyxJQUFJO3dCQUNuQixDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7b0JBQ2pDLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLFlBQVksQ0FBQyxFQUFFLEdBQUc7aUJBQzdDO2dCQUNELG1DQUFtQztnQkFDbkMscUJBQXFCO2dCQUNyQixXQUFXO2dCQUNYLElBQUk7YUFDTDtZQUNELDBDQUEwQztZQUUxQyxJQUFJLFFBQVEsS0FBSyxrQkFBa0IsRUFBRTtnQkFDbkMsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLFlBQVksQ0FBQyxFQUFFO29CQUN2RCxxQ0FBcUM7aUJBQ3RDO3FCQUFNO29CQUNMLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTt3QkFDaEIsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUE7cUJBQ25EO29CQUNELG9CQUFvQixHQUFHLElBQUksQ0FBQTtpQkFDNUI7YUFDRjtZQUVELDhDQUE4QztZQUM5QyxJQUFJLFFBQVEsS0FBSyxTQUFTLElBQUksUUFBUSxLQUFLLHFCQUFxQjtnQkFDNUQsUUFBUSxLQUFLLFNBQVMsSUFBSSxRQUFRLEtBQUssWUFBWTtnQkFDbkQsUUFBUSxLQUFLLHVCQUF1QixJQUFJLFFBQVEsS0FBSyxVQUFVLEVBQUU7Z0JBQ25FLG9CQUFvQixHQUFHLElBQUksQ0FBQTthQUM1QjtTQUNGO1FBRUQsNENBQTRDO1FBQzVDLElBQUksb0JBQW9CLEVBQUU7WUFDeEIsSUFBSSxDQUFDLDBCQUEwQixFQUFFLENBQUE7U0FDbEM7UUFDRCx5REFBeUQ7UUFDekQsaUVBQWlFO0lBQ25FLENBQUM7SUFFRCxLQUFLLENBQUMsT0FBWTtRQUNoQixJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDckIsT0FBTyxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsSUFBSSxPQUFPLENBQUMsWUFBWSxDQUFBO1NBQ3BHO1FBQ0QsT0FBTyxPQUFPLENBQUMsWUFBWSxDQUFBO0lBQzdCLENBQUM7SUFFRCxJQUFJLFlBQVk7UUFDZCxJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtZQUMxQixPQUFPLElBQUksQ0FBQyxtQkFBbUIsQ0FBQTtTQUNoQztRQUNELElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNoQixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxLQUFLLFNBQVMsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFBO1NBQ2pFO1FBQ0QsT0FBTyxLQUFLLENBQUE7SUFDZCxDQUFDO0lBRUQsSUFBSSxRQUFRO1FBQ1YsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUU7WUFDMUIsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFBO1NBQzVCO1FBQ0QsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ2hCLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQTtTQUMxRTtRQUNELE9BQU8sS0FBSyxDQUFBO0lBQ2QsQ0FBQztJQUVNLFdBQVcsQ0FBQyxPQUFrQztRQUNuRCxJQUFJLE9BQU8sRUFBRTtZQUNYLE9BQU8sT0FBTyxDQUFDLGVBQWUsS0FBSyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFBO1NBQ3JFO1FBQ0QsT0FBTyxLQUFLLENBQUE7SUFDZCxDQUFDO0lBRUQsYUFBYSxDQUFDLE9BQVk7UUFDeEIsSUFBSSxPQUFPLEVBQUU7WUFDWCxPQUFPLE9BQU8sQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQTtTQUNyRTtRQUNELE9BQU8sS0FBSyxDQUFBO0lBQ2QsQ0FBQztJQUVELElBQUksZ0JBQWdCO1FBQ2xCLElBQUksSUFBSSxDQUFDLFNBQVMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFO1lBQzFHLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFBO1lBQzNDLElBQUksU0FBUyxJQUFJLFNBQVMsQ0FBQyxPQUFPLEVBQUU7Z0JBQ2xDLE1BQU0sR0FBRyxHQUFHLE1BQU0sRUFBRSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQTtnQkFDekMsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUE7Z0JBQ2xFLE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUE7Z0JBQ3hGLE9BQU87Z0JBQ0wsa0JBQWtCO2dCQUNsQixNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQzt1QkFDbEMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FDdEMsQ0FBQTthQUNGO1lBQUMsT0FBTyxJQUFJLENBQUE7U0FDZDtRQUNELE9BQU8sS0FBSyxDQUFBO0lBQ2QsQ0FBQztJQUVELElBQUksVUFBVTtRQUNaLElBQUksSUFBSSxDQUFDLGlCQUFpQixFQUFFO1lBQzFCLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixDQUFBO1NBQzlCO1FBQ0QsT0FBTyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQTtJQUNqQyxDQUFDO0lBRUQsSUFBSSxZQUFZO1FBQ2QsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUU7WUFDMUIsT0FBTyxJQUFJLENBQUMsbUJBQW1CLENBQUE7U0FDaEM7UUFDRCxPQUFPLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFBO0lBQ25DLENBQUM7SUFFTSxhQUFhO1FBQ2xCLG9DQUFvQztRQUNwQyxxQkFBcUI7UUFDckIsbUVBQW1FO1FBQ25FLHFCQUFxQjtRQUNyQixJQUFJO1FBQ0osa0VBQWtFO1FBQ2xFLHFCQUFxQjtRQUNyQixJQUFJO1FBRUosT0FBTyxTQUFTLENBQUE7SUFDbEIsQ0FBQztJQUNNLGNBQWM7UUFDbkIsT0FBTyxTQUFTLENBQUE7SUFDbEIsQ0FBQztJQUVPLGtDQUFrQztRQUN4QyxJQUFJLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFO1lBQ3pFLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQXlCLEVBQUUsRUFBRTtnQkFDMUQsSUFBSSxLQUFLLENBQUMsZUFBZSxLQUFLLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUU7b0JBQy9ELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFBO2lCQUNsQztxQkFBTSxJQUFJLEtBQUssQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLGtCQUFrQixFQUFFO29CQUNsRixJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQTtpQkFDakM7cUJBQU0sSUFBSSxLQUFLLENBQUMsZUFBZSxLQUFLLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUU7b0JBQ3RFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxjQUFjLElBQUksQ0FBQyxDQUFBO2lCQUMxQztxQkFBTSxJQUFJLEtBQUssQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLGVBQWUsRUFBRTtvQkFDL0UsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGNBQWMsSUFBSSxDQUFDLENBQUE7aUJBQzFDO3FCQUFNLElBQUksS0FBSyxDQUFDLGVBQWUsS0FBSyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxFQUFFO29CQUN4RSxRQUFRLEtBQUssQ0FBQyxRQUFRLEVBQUU7d0JBQ3RCLEtBQUssU0FBUyxDQUFDLFVBQVUsQ0FBQyxRQUFROzRCQUNoQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxJQUFJLENBQUMsQ0FBQTs0QkFDbEMsTUFBSzt3QkFDUCxLQUFLLFNBQVMsQ0FBQyxVQUFVLENBQUMsR0FBRzs0QkFDM0IsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sSUFBSSxDQUFDLENBQUE7NEJBQ2xDLE1BQUs7d0JBQ1AsS0FBSyxTQUFTLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQzt3QkFDOUIsS0FBSyxTQUFTLENBQUMsVUFBVSxDQUFDLElBQUk7NEJBQzVCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFBOzRCQUNoQyxNQUFLO3dCQUNQLEtBQUssU0FBUyxDQUFDLFVBQVUsQ0FBQyxXQUFXOzRCQUNuQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsZ0JBQWdCLElBQUksQ0FBQyxDQUFBOzRCQUMzQyxNQUFLO3dCQUNQLEtBQUssU0FBUyxDQUFDLFVBQVUsQ0FBQyxHQUFHOzRCQUMzQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQTs0QkFDOUIsTUFBSzt3QkFDUCxLQUFLLFNBQVMsQ0FBQyxVQUFVLENBQUMsZUFBZTs0QkFDdkMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGNBQWMsSUFBSSxDQUFDLENBQUE7NEJBQ3pDLE1BQUs7d0JBQ1AsS0FBSyxTQUFTLENBQUMsVUFBVSxDQUFDLE1BQU07NEJBQzlCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFBOzRCQUNqQyxNQUFLO3dCQUNQLEtBQUssU0FBUyxDQUFDLFVBQVUsQ0FBQyxJQUFJOzRCQUM1QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxJQUFJLENBQUMsQ0FBQTs0QkFDbEMsTUFBSzt3QkFDUCxLQUFLLFNBQVMsQ0FBQyxVQUFVLENBQUMsSUFBSTs0QkFDNUIsSUFBSSxLQUFLLENBQUMsWUFBWSxLQUFLLFlBQVksRUFBRTtnQ0FDdkMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsSUFBSSxDQUFDLENBQUE7NkJBQ3RDO2lDQUFNO2dDQUNMLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFBOzZCQUNoQzs0QkFDRCxNQUFLO3dCQUNQLEtBQUssU0FBUyxDQUFDLFVBQVUsQ0FBQyxpQkFBaUI7NEJBQ3pDLDhDQUE4Qzs0QkFDOUMsK0NBQStDOzRCQUMvQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxJQUFJLENBQUMsQ0FBQTs0QkFDdkMsTUFBSzt3QkFDUCxLQUFLLFNBQVMsQ0FBQyxVQUFVLENBQUMsVUFBVTs0QkFDbEMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsSUFBSSxDQUFDLENBQUE7NEJBQ3BDLE1BQUs7d0JBQ1AsS0FBSyxTQUFTLENBQUMsVUFBVSxDQUFDLE9BQU87NEJBQy9CLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFBOzRCQUNsQyxNQUFLO3dCQUNQOzRCQUNFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFBOzRCQUNoQyxNQUFLO3FCQUNSO2lCQUNGO1lBQ0gsQ0FBQyxDQUFDLENBQUE7U0FDSDtRQUNELEtBQUssTUFBTSxHQUFHLElBQUksSUFBSSxDQUFDLGdCQUFnQixFQUFFO1lBQ3ZDLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRTtnQkFDbEMsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQTthQUNoQztTQUNGO0lBQ0gsQ0FBQztJQUVELElBQUksV0FBVztRQUNiLE9BQU87WUFDTCxTQUFTLEVBQUUsSUFBSSxDQUFDLE1BQU07WUFDdEIsV0FBVyxFQUFFLElBQUksQ0FBQyxlQUFlO1lBQ2pDLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztTQUN0QixDQUFBO0lBQ0gsQ0FBQztJQUVNLGNBQWMsQ0FBQyxNQUFjLEVBQUUsT0FBMkI7UUFDL0QsSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNaLE9BQU8sSUFBSSxDQUFBO1NBQ1o7UUFDRCxPQUFPLE9BQU8sQ0FBQyxVQUFVLENBQUE7SUFDM0IsQ0FBQztJQUVNLGNBQWM7UUFDbkIsa0NBQWtDO1FBQ2xDLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNoQixJQUFJLENBQUMsTUFBTSxDQUFDLHNCQUFzQixDQUNoQztnQkFDRSxJQUFJLEVBQUUsT0FBTztnQkFDYixPQUFPLEVBQUUscUJBQXFCO2dCQUM5QixxQ0FBcUM7YUFDdEMsRUFDRDtnQkFDRSw0Q0FBNEM7Z0JBQzVDLDZDQUE2QztnQkFDN0MsRUFBRSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxJQUFJLEVBQUU7Z0JBQ2pDLElBQUksRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWU7Z0JBQ2xDLE1BQU0sRUFBRTtvQkFDTixFQUFFLEVBQUUsSUFBSSxDQUFDLE1BQU0sSUFBSSxFQUFFO2lCQUN0QjtnQkFDRCxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sR0FBRyxFQUFFLEVBQUU7YUFDcEMsRUFDRDtnQkFDRSxTQUFTLEVBQUUsR0FBRyxDQUFDLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUFDLE9BQU87Z0JBQzlELE1BQU0sRUFBRSxDQUFDLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUFDO2FBQ2xELENBQUMsQ0FBQTtTQUNMO0lBQ0gsQ0FBQztJQUNELElBQUksU0FBUztRQUNYLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNoQixPQUFPLENBQUMsQ0FBQyxTQUFTLENBQUMsMkNBQTJDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUE7U0FDcEc7UUFBQyxPQUFPLEtBQUssQ0FBQTtJQUNoQixDQUFDO0lBRUQsSUFBSSxTQUFTO1FBQ1gsT0FBTyxJQUFJLENBQUE7SUFDYixDQUFDO0lBRUQsSUFBSSxVQUFVO1FBQ1osT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQTtJQUNwQyxDQUFDO0lBRUQsb0JBQW9CLENBQUMsVUFBa0I7UUFDckMsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxFQUFFO1lBQzlELElBQUksZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFBO1lBQ3hELElBQ0UsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLGVBQWUsS0FBSyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsUUFBUTttQkFDckUsZ0JBQWdCLENBQUMsZUFBZSxLQUFLLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxpQkFBaUI7bUJBQ2pGLGdCQUFnQixDQUFDLGVBQWUsS0FBSyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsZ0JBQWdCO21CQUNoRixnQkFBZ0IsQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLGVBQWUsQ0FBQyxFQUNyRjtnQkFDQSxxQkFBcUI7Z0JBQ3JCLHNGQUFzRjtnQkFDdEYsa0ZBQWtGO2dCQUNsRiw2Q0FBNkM7Z0JBQzdDLCtCQUErQjtnQkFDL0Isa0JBQWtCO2dCQUNsQixnSkFBZ0o7Z0JBQ2hKLElBQUk7Z0JBQ0osSUFBSSxnQkFBZ0IsQ0FBQyxlQUFlLEtBQUssU0FBUyxDQUFDLGdCQUFnQixDQUFDLE1BQU0sRUFBRTtvQkFDMUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUNoRyxDQUFDLEdBQVEsRUFBRSxPQUFZLEVBQUUsRUFBRTt3QkFDekIsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxFQUFFOzRCQUMzRCxPQUFPLEdBQUcsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLENBQUMsZ0JBQWdCLElBQUksQ0FBQyxDQUFDLENBQUE7eUJBQ3JIO29CQUVILENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQTtpQkFDUjtnQkFDRCxpQkFBaUI7Z0JBQ2pCLE1BQU0sY0FBYyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUMsb0JBQW9CLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFBO2dCQUMzTixNQUFNLFVBQVUsR0FBRyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxFQUFFLGdCQUFnQixDQUFDLENBQUMsSUFBSSxDQUFDLENBQUE7Z0JBQy9GLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxzQkFBc0IsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFDLE1BQU0sR0FBRyxVQUFVLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFBO2dCQUMxSCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxvQkFBb0IsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7YUFDaEk7WUFDRCxPQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQTtTQUN6QztRQUNELE9BQU8sRUFBRSxDQUFBO0lBQ1gsQ0FBQztJQUVELHVCQUF1QixDQUFDLFVBQWtCO1FBQ3hDLHFEQUFxRDtRQUNyRCx5RkFBeUY7UUFDekYscURBQXFEO1FBQ3JELElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDLG9CQUFvQixJQUFJLENBQUMsQ0FBQTtRQUN2SSxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUE7SUFDckMsQ0FBQztJQUVELGNBQWMsQ0FBQyxLQUFhO1FBQzFCLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFO1lBQzVCLE9BQU8sVUFBVSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtTQUNwQztRQUNELE9BQU8sS0FBSyxDQUFBO0lBQ2QsQ0FBQztJQUdELG1CQUFtQixDQUFDLFVBQWtCO1FBQ3BDLHFDQUFxQztRQUNyQyxxREFBcUQ7UUFDckQsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQTtJQUN6SCxDQUFDO0lBRUQscUJBQXFCLENBQUMsUUFBYTtRQUNqQyxNQUFNLEdBQUcsR0FBRyxRQUFRLENBQUE7UUFDcEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsMEJBQTBCLEVBQUU7WUFDM0MsbUJBQW1CO1lBQ25CLEtBQUssRUFBRSxRQUFRO1lBQ2YsSUFBSSxFQUFFLEVBQUUsR0FBRyxFQUFFO1lBQ2IseUNBQXlDO1NBQzFDLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFDRCxVQUFVO1FBQ1IsSUFBSTtZQUNGLElBQUksVUFBVSxHQUFRLElBQUksQ0FBQyxRQUFRLENBQUMsaUJBQWlCLENBQUMsc0NBQXNDLENBQUMsQ0FBQTtZQUM3RixJQUFJLFVBQVUsRUFBRTtnQkFDZCxVQUFVLENBQUMsY0FBYyxDQUFDLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFBO2FBQ3JGO1lBQ0QsSUFBSSxJQUFJLENBQUMsYUFBYSxLQUFLLEtBQUssRUFBRTtnQkFDaEMsSUFBSSxVQUFVLEVBQUU7b0JBQ2QsTUFBTSxJQUFJLEdBQUcsVUFBVSxDQUFDLHFCQUFxQixFQUFFLENBQUE7b0JBQy9DLElBQUksSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxFQUFFO3dCQUN0QixNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFBO3FCQUNuQztpQkFDRjthQUNGO1lBQ0QsVUFBVSxDQUFDLEdBQUcsRUFBRTtnQkFDZCxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7WUFDMUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFBO1lBRVAsU0FBUztZQUNULDBGQUEwRjtZQUMxRixxREFBcUQ7WUFDckQscUNBQXFDO1lBQ3JDLElBQUk7U0FDTDtRQUFDLE9BQU8sR0FBRyxFQUFFO1NBQ2I7SUFDSCxDQUFDO0lBRUQsbUJBQW1CLENBQUMsZUFBb0I7UUFDdEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsQ0FDaEM7WUFDRSxJQUFJLEVBQUUsUUFBUSxDQUFDLGlCQUFpQixDQUFDLEtBQUs7WUFDdEMsRUFBRSxFQUFFLGtCQUFrQjtZQUN0QixPQUFPLEVBQUUsUUFBUSxDQUFDLG9CQUFvQixDQUFDLFdBQVc7U0FDbkQsRUFDRDtZQUNFLEVBQUUsRUFBRSxlQUFlO1lBQ25CLElBQUksRUFBRSxRQUFRLENBQUMsb0JBQW9CLENBQUMsV0FBVztTQUNoRCxDQUFDLENBQUE7UUFDSixJQUFJLGVBQWUsRUFBRTtZQUNuQixJQUFJLENBQUMsMEJBQTBCLEdBQUcsSUFBSSxDQUFBO1lBQ3RDLElBQUksUUFBUSxHQUFRLGVBQWUsQ0FBQTtZQUNuQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsc0JBQXNCLENBQUMsUUFBUSxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsR0FBUSxFQUFFLEVBQUU7Z0JBQzlFLElBQUksQ0FBQywwQkFBMEIsR0FBRyxLQUFLLENBQUE7Z0JBQ3ZDLE1BQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFBO2dCQUMvQixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQywwQkFBMEIsRUFBRTtvQkFDM0MsS0FBSyxFQUFFLFFBQVE7b0JBQ2YsSUFBSSxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxRQUFRLENBQUMsVUFBVSxFQUFFO2lCQUMzQyxDQUFDLENBQUE7WUFDSixDQUFDLENBQUMsQ0FBQTtTQUNIO2FBQU07WUFDTCxJQUFJLENBQUMsMEJBQTBCLEdBQUcsS0FBSyxDQUFBO1NBQ3hDO0lBQ0gsQ0FBQztJQUNELFdBQVc7UUFDVCxJQUFJLElBQUksQ0FBQyxzQkFBc0IsRUFBRTtZQUMvQixJQUFJLENBQUMsc0JBQXNCLENBQUMsV0FBVyxFQUFFLENBQUE7U0FDMUM7SUFDSCxDQUFDO0lBRUQsSUFBSSxzQkFBc0I7UUFDeEIsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUU7WUFDMUIsT0FBTyxJQUFJLENBQUMsNkJBQTZCLENBQUE7U0FDMUM7UUFDRCxPQUFPLElBQUksQ0FBQyw2QkFBNkIsRUFBRSxDQUFBO0lBQzdDLENBQUM7SUFFRCxJQUFJLGlCQUFpQjtRQUNuQixJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtZQUMxQixPQUFPLElBQUksQ0FBQyx3QkFBd0IsQ0FBQTtTQUNyQztRQUNELE9BQU8sSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUE7SUFDeEMsQ0FBQztJQUVELElBQUksdUJBQXVCO1FBQ3pCLElBQUksSUFBSSxDQUFDLGlCQUFpQixFQUFFO1lBQzFCLE9BQU8sSUFBSSxDQUFDLDhCQUE4QixDQUFBO1NBQzNDO1FBQ0QsT0FBTyxJQUFJLENBQUMsOEJBQThCLEVBQUUsQ0FBQTtJQUM5QyxDQUFDO0lBRUQsSUFBSSxpQkFBaUI7UUFDbkIsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUU7WUFDMUIsT0FBTyxJQUFJLENBQUMsd0JBQXdCLENBQUE7U0FDckM7UUFDRCxPQUFPLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFBO0lBQ3hDLENBQUM7SUFFRCxJQUFJLHFCQUFxQjtRQUN2QixJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtZQUMxQixPQUFPLElBQUksQ0FBQyw0QkFBNEIsQ0FBQTtTQUN6QztRQUNELE9BQU8sSUFBSSxDQUFDLDRCQUE0QixFQUFFLENBQUE7SUFDNUMsQ0FBQztJQUVELElBQUksMkJBQTJCO1FBQzdCLElBQUksSUFBSSxDQUFDLGlCQUFpQixFQUFFO1lBQzFCLE9BQU8sSUFBSSxDQUFDLGtDQUFrQyxDQUFBO1NBQy9DO1FBQ0QsT0FBTyxJQUFJLENBQUMsa0NBQWtDLEVBQUUsQ0FBQTtJQUNsRCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssK0JBQStCLENBQUMsV0FBbUI7UUFDekQsSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUU7WUFDN0YsNEVBQTRFO1lBQzVFLE9BQU8sSUFBSSxDQUFDLGtDQUFrQyxDQUFDLFdBQVcsQ0FBQyxDQUFBO1NBQzVEO1FBRUQsOENBQThDO1FBQzlDLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxXQUFXLENBQUMsQ0FBQTtRQUMzRixJQUFJLENBQUMsZ0JBQWdCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUU7WUFDbkQsT0FBTyxJQUFJLENBQUMsa0NBQWtDLENBQUMsV0FBVyxDQUFDLENBQUE7U0FDNUQ7UUFFRCw4Q0FBOEM7UUFDOUMsSUFBSSxvQkFBb0IsR0FBRyxJQUFJLENBQUE7UUFDL0IsSUFBSSxhQUFhLEdBQUcsS0FBSyxDQUFBO1FBQ3pCLElBQUksa0JBQWtCLEdBQUcsS0FBSyxDQUFBO1FBRTlCLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFVLEVBQUUsRUFBRTtZQUMvQyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFBO1lBQ3pELE1BQU0sWUFBWSxHQUFHLEtBQUssQ0FBQyxlQUFlLEtBQUssbUJBQW1CO2dCQUNoRSxLQUFLLENBQUMsY0FBYyxLQUFLLG1CQUFtQjtnQkFDNUMsS0FBSyxDQUFDLGVBQWUsS0FBSyxrQkFBa0IsQ0FBQTtZQUM5QyxNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsU0FBUyxLQUFLLElBQUksSUFBSSxLQUFLLENBQUMsZUFBZSxLQUFLLElBQUksQ0FBQTtZQUU5RSxJQUFJLFlBQVksRUFBRTtnQkFDaEIsYUFBYSxHQUFHLElBQUksQ0FBQTtnQkFDcEIsSUFBSSxTQUFTLElBQUksQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLEtBQUssQ0FBQyxJQUFJLFNBQVMsQ0FBQyxvQkFBb0IsSUFBSSxHQUFHLENBQUMsRUFBRTtvQkFDNUYsa0JBQWtCLEdBQUcsSUFBSSxDQUFBO2lCQUMxQjthQUNGO2lCQUFNLElBQUksV0FBVyxFQUFFO2dCQUN0QiwwQ0FBMEM7Z0JBQzFDLElBQUksQ0FBQyxTQUFTLElBQUksQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLEtBQUssQ0FBQyxJQUFJLFNBQVMsQ0FBQyxvQkFBb0IsR0FBRyxHQUFHLENBQUMsRUFBRTtvQkFDNUYsb0JBQW9CLEdBQUcsS0FBSyxDQUFBO2lCQUM3QjthQUNGO1FBQ0gsQ0FBQyxDQUFDLENBQUE7UUFFRixPQUFPLENBQUMsR0FBRyxDQUFDLDBCQUEwQixFQUFFLEVBQUUsb0JBQW9CLEVBQUUsYUFBYSxFQUFFLGtCQUFrQixFQUFFLENBQUMsQ0FBQTtRQUVwRyxxR0FBcUc7UUFDckcsT0FBTyxhQUFhLENBQUMsQ0FBQyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQTtJQUNsRSxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSyxrQ0FBa0MsQ0FBQyxXQUFtQjtRQUM1RCxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFO1lBQzFCLE9BQU8sS0FBSyxDQUFBO1NBQ2I7UUFFRCw0REFBNEQ7UUFDNUQsTUFBTSxZQUFZLEdBQUcsUUFBUSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQ2xFLE1BQU0sNEJBQTRCLEdBQUcsWUFBWSxHQUFHLENBQUMsQ0FBQSxDQUFDLGlDQUFpQztRQUV2RixPQUFPLENBQUMsR0FBRyxDQUFDLGFBQWEsV0FBVyxVQUFVLFlBQVksY0FBYyw0QkFBNEIsd0JBQXdCLENBQUMsQ0FBQTtRQUU3SCxJQUFJLDRCQUE0QixJQUFJLENBQUMsRUFBRTtZQUNyQyxPQUFPLElBQUksQ0FBQSxDQUFDLG1DQUFtQztTQUNoRDtRQUVELGdGQUFnRjtRQUNoRixpR0FBaUc7UUFDakcsSUFBSSxpQ0FBaUMsR0FBRyxDQUFDLENBQUE7UUFDekMsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsVUFBVSxDQUFBO1FBRTlELEtBQUssTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsRUFBRTtZQUNwRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUE7WUFFdkMsOENBQThDO1lBQzlDLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxLQUFLLG1CQUFtQixJQUFJLElBQUksQ0FBQyxjQUFjLEtBQUssbUJBQW1CLENBQUM7Z0JBQy9GLENBQUMsSUFBSSxDQUFDLGdCQUFnQixLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsb0JBQW9CLElBQUksR0FBRyxDQUFDLEVBQUU7Z0JBRW5FLG9HQUFvRztnQkFDcEcsb0ZBQW9GO2dCQUNwRixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssaUJBQWlCLENBQUE7Z0JBRWxFLElBQUksU0FBUyxFQUFFO29CQUNiLGlDQUFpQyxFQUFFLENBQUE7b0JBQ25DLE9BQU8sQ0FBQyxHQUFHLENBQUMseUNBQXlDLEdBQUcsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFBO2lCQUNsRTtxQkFBTTtvQkFDTCxPQUFPLENBQUMsR0FBRyxDQUFDLGtEQUFrRCxHQUFHLEVBQUUsQ0FBQyxDQUFBO2lCQUNyRTthQUNGO1NBQ0Y7UUFFRCxPQUFPLENBQUMsR0FBRyxDQUFDLDBDQUEwQyxpQ0FBaUMsZUFBZSw0QkFBNEIsRUFBRSxDQUFDLENBQUE7UUFFckksMkVBQTJFO1FBQzNFLE9BQU8saUNBQWlDLElBQUksNEJBQTRCLENBQUE7SUFDMUUsQ0FBQztJQUVPLHNCQUFzQixDQUFDLE9BQVksRUFBRSxVQUFrQjtRQUM3RCxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU8sSUFBSSxDQUFBO1FBQ3pCLElBQUksT0FBTyxDQUFDLFVBQVUsS0FBSyxVQUFVO1lBQUUsT0FBTyxPQUFPLENBQUE7UUFDckQsSUFBSSxPQUFPLENBQUMsUUFBUSxFQUFFO1lBQ3BCLEtBQUssTUFBTSxLQUFLLElBQUksT0FBTyxDQUFDLFFBQVEsRUFBRTtnQkFDcEMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUFDLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQTtnQkFDNUQsSUFBSSxLQUFLO29CQUFFLE9BQU8sS0FBSyxDQUFBO2FBQ3hCO1NBQ0Y7UUFDRCxPQUFPLElBQUksQ0FBQTtJQUNiLENBQUM7SUFFRCxJQUFJLG1CQUFtQjtRQUNyQixJQUFJLElBQUksQ0FBQyxTQUFTLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDeEQsT0FBTztnQkFDTCxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVztnQkFDaEMsYUFBYSxFQUFFLE1BQU07YUFDdEIsQ0FBQTtTQUNGO1FBQ0QsT0FBTyxJQUFJLENBQUE7SUFDYixDQUFDO0lBRUQsSUFBSSxXQUFXO1FBQ2IsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUU7WUFDMUIsT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQUE7U0FDL0I7UUFDRCxPQUFPLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFBO0lBQ2xDLENBQUM7SUFFRCwwQkFBMEI7UUFDeEIsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUU7WUFDM0MsT0FBTyxDQUFDLENBQUE7U0FDVDtRQUNELE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFBO1FBQ3BFLElBQUksQ0FBQyxhQUFhLElBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxFQUFFO1lBQzlDLE9BQU8sQ0FBQyxDQUFBO1NBQ1Q7UUFDRCxJQUFJLGNBQWMsR0FBRyxDQUFDLENBQUE7UUFDdEIsYUFBYSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFjLEVBQUUsRUFBRTtZQUNqRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUE7WUFDOUMsSUFBSSxRQUFRLElBQUksUUFBUSxDQUFDLGdCQUFnQixLQUFLLENBQUMsRUFBRTtnQkFDL0MsY0FBYyxFQUFFLENBQUE7YUFDakI7UUFDSCxDQUFDLENBQUMsQ0FBQTtRQUNGLE9BQU8sY0FBYyxDQUFBO0lBQ3ZCLENBQUM7SUFFRDs7T0FFRztJQUNILHlCQUF5QjtRQUN2QixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtZQUMzQyxPQUFPLEVBQUUsQ0FBQTtTQUNWO1FBRUQsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUE7UUFDcEUsSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUNsQixPQUFPLEVBQUUsQ0FBQTtTQUNWO1FBRUQsbURBQW1EO1FBQ25ELElBQUksYUFBYSxDQUFDLGFBQWEsRUFBRTtZQUMvQixPQUFPLGFBQWEsQ0FBQyxhQUFhLENBQUE7U0FDbkM7UUFFRCxNQUFNLGNBQWMsR0FBRyxhQUFhLENBQUMsY0FBYyxDQUFBO1FBRW5ELGlEQUFpRDtRQUNqRCxJQUFJLGNBQWMsS0FBSyxDQUFDLEVBQUU7WUFDeEIsT0FBTyw4REFBOEQsQ0FBQTtTQUN0RTtRQUVELHlEQUF5RDtRQUN6RCxPQUFPLDhEQUE4RCxjQUFjLDJCQUEyQixDQUFBO0lBQ2hILENBQUM7SUFFRDs7T0FFRztJQUNILDZCQUE2QjtRQUMzQixJQUFJLENBQUMsSUFBSSxDQUFDLHVCQUF1QixFQUFFO1lBQ2pDLE9BQU8sRUFBRSxDQUFBO1NBQ1Y7UUFDRCxPQUFPLDJFQUEyRSxDQUFBO0lBQ3BGLENBQUM7SUFFRDs7T0FFRztJQUNILHdCQUF3QjtRQUN0QixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtZQUMzQyxPQUFPLEVBQUUsQ0FBQTtTQUNWO1FBRUQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUE7UUFFL0QsNERBQTREO1FBQzVELElBQUksUUFBUSxJQUFJLFFBQVEsQ0FBQyxxQkFBcUIsRUFBRTtZQUM5QyxPQUFPLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQTtTQUN0QztRQUVELElBQUksSUFBSSxDQUFDLDJCQUEyQixFQUFFO1lBQ3BDLE9BQU8sZ0ZBQWdGLENBQUE7U0FDeEY7UUFFRCxPQUFPLEVBQUUsQ0FBQTtJQUNYLENBQUM7SUFFRCx3QkFBd0IsQ0FBQyxPQUFrQztRQUN6RCxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ1osT0FBTyxLQUFLLENBQUE7U0FDYjtRQUVELCtEQUErRDtRQUMvRCxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRTtZQUN4QixPQUFPLEtBQUssQ0FBQTtTQUNiO1FBRUQsZ0VBQWdFO1FBQ2hFLElBQUksQ0FBQyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsY0FBYztZQUMzQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsY0FBYyxLQUFLLFNBQVMsQ0FBQyxlQUFlLENBQUMsVUFBVSxFQUFFO1lBQ2xGLE9BQU8sS0FBSyxDQUFBO1NBQ2I7UUFFRCx5RUFBeUU7UUFDekUsSUFBSSxJQUFJLENBQUMsVUFBVSxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxFQUFFO1lBQ2pFLE9BQU8sS0FBSyxDQUFBO1NBQ2I7UUFFRCxxRUFBcUU7UUFDckUsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQ3hDLE9BQU8sS0FBSyxDQUFBO1NBQ2I7UUFFRCxpQ0FBaUM7UUFDakMsTUFBTSxxQkFBcUIsR0FBRztZQUM1QixTQUFTLENBQUMsVUFBVSxDQUFDLEdBQUc7U0FDekIsQ0FBQTtRQUVELE9BQU8scUJBQXFCLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQTtJQUN6RCxDQUFDO0lBRUQsZUFBZSxDQUFDLE9BQTJCLEVBQUUsS0FBa0I7UUFDN0QsSUFBSSxLQUFLLEVBQUU7WUFDVCxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUE7WUFDdEIsS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFBO1NBQ3hCO1FBQ0QsTUFBTSxNQUFNLEdBQUcsa0JBQWtCLE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FBQTtRQUNyRCxJQUFJLENBQUMseUJBQXlCLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQTtRQUMzRCxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsQ0FBQTtRQUMvQixPQUFPLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsQ0FBQTtJQUN0RCxDQUFDO0lBSUQ7O09BRUc7SUFDSCx3QkFBd0IsQ0FBQyxLQUFrQjtRQUN6QyxJQUFJLEtBQUssRUFBRTtZQUNULEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQTtZQUN0QixLQUFLLENBQUMsZUFBZSxFQUFFLENBQUE7U0FDeEI7UUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFO1lBQzdELE9BQU07U0FDUDtRQUVELHlDQUF5QztRQUN6QyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLFdBQVcsRUFBRSxNQUFNLENBQUE7UUFDbEQsSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQTtZQUNsQyxPQUFNO1NBQ1A7UUFFRCx5RUFBeUU7UUFDekUscUVBQXFFO1FBQ3JFLElBQUksV0FBVyxHQUFHLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUEsQ0FBQyxxREFBcUQ7UUFFOUYsd0RBQXdEO1FBQ3hELElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUU7WUFDckIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLG9CQUFvQixDQUFDLENBQUE7WUFDM0QsSUFBSSxLQUFLLEVBQUU7Z0JBQ1QsV0FBVyxHQUFHLEdBQUcsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUE7YUFDN0I7U0FDRjtRQUVELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxVQUFVLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQTtRQUVwRSxJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFBO1FBRTlCLElBQUksQ0FBQyxTQUFTLENBQUMsNEJBQTRCLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLFdBQVcsQ0FBQyxDQUFDLFNBQVMsQ0FBQztZQUNqRyxJQUFJLEVBQUUsQ0FBQyxRQUFhLEVBQUUsRUFBRTtnQkFDdEIsSUFBSSxDQUFDLGtCQUFrQixHQUFHLEtBQUssQ0FBQTtnQkFDL0IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxxQ0FBcUMsRUFBRSxRQUFRLENBQUMsQ0FBQTtnQkFDNUQsNkNBQTZDO2dCQUM3QyxJQUFJLFFBQVEsSUFBSSxRQUFRLENBQUMsTUFBTSxFQUFFO29CQUMvQix3Q0FBd0M7b0JBQ3hDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLDBCQUEwQixFQUFFO3dCQUMzQyxLQUFLLEVBQUUsUUFBUTt3QkFDZixJQUFJLEVBQUU7NEJBQ0osR0FBRyxFQUFFLFFBQVEsQ0FBQyxNQUFNLENBQUMsUUFBUSxJQUFJLFFBQVEsQ0FBQyxNQUFNLENBQUMsT0FBTzs0QkFDeEQsTUFBTSxFQUFFLFFBQVEsQ0FBQyxNQUFNLENBQUMsVUFBVTs0QkFDbEMsYUFBYSxFQUFFLElBQUk7eUJBQ3BCO3FCQUNGLENBQUMsQ0FBQTtpQkFDSDtZQUNILENBQUM7WUFDRCxLQUFLLEVBQUUsQ0FBQyxLQUFVLEVBQUUsRUFBRTtnQkFDcEIsSUFBSSxDQUFDLGtCQUFrQixHQUFHLEtBQUssQ0FBQTtnQkFDL0IsaUNBQWlDO2dCQUNqQyxNQUFNLFlBQVksR0FBRyxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxPQUFPLElBQUksS0FBSyxFQUFFLE9BQU8sSUFBSSxnQ0FBZ0MsQ0FBQTtnQkFDeEcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLE9BQU8sRUFBRTtvQkFDeEMsUUFBUSxFQUFFLElBQUk7b0JBQ2Qsa0JBQWtCLEVBQUUsUUFBUTtvQkFDNUIsZ0JBQWdCLEVBQUUsUUFBUTtvQkFDMUIsVUFBVSxFQUFFLENBQUMsZ0JBQWdCLENBQUM7aUJBQy9CLENBQUMsQ0FBQTtnQkFDRixPQUFPLENBQUMsS0FBSyxDQUFDLCtCQUErQixFQUFFLEtBQUssQ0FBQyxDQUFBO1lBQ3ZELENBQUM7U0FDRixDQUFDLENBQUE7SUFDSixDQUFDOytHQXByQ1UsNEJBQTRCO21HQUE1Qiw0QkFBNEIsZ2pCQ2xDekMscXpsRUEreUJlLGtnV0Q3d0JGLDRCQUE0Qix5a0JBWjNCO1lBQ1YsT0FBTyxDQUFDLFlBQVksRUFBRTtnQkFDcEIsVUFBVSxDQUFDLFdBQVcsRUFBRTtvQkFDdEIsS0FBSyxDQUFDLEVBQUUsU0FBUyxFQUFFLGtCQUFrQixFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQztvQkFDdEQsT0FBTyxDQUFDLEdBQUcsQ0FBQztpQkFDYixDQUFDO2dCQUNGLFVBQVUsQ0FBQyxXQUFXLEVBQUU7b0JBQ3RCLE9BQU8sQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLEVBQUUsU0FBUyxFQUFFLGtCQUFrQixFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO2lCQUNyRSxDQUFDO2FBQ0gsQ0FBQztTQUNIOzs0RkFFVSw0QkFBNEI7a0JBaEJ4QyxTQUFTOytCQUNFLG1DQUFtQyxjQUdqQzt3QkFDVixPQUFPLENBQUMsWUFBWSxFQUFFOzRCQUNwQixVQUFVLENBQUMsV0FBVyxFQUFFO2dDQUN0QixLQUFLLENBQUMsRUFBRSxTQUFTLEVBQUUsa0JBQWtCLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDO2dDQUN0RCxPQUFPLENBQUMsR0FBRyxDQUFDOzZCQUNiLENBQUM7NEJBQ0YsVUFBVSxDQUFDLFdBQVcsRUFBRTtnQ0FDdEIsT0FBTyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsRUFBRSxTQUFTLEVBQUUsa0JBQWtCLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7NkJBQ3JFLENBQUM7eUJBQ0gsQ0FBQztxQkFDSDsyV0FHUSxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLG1CQUFtQjtzQkFBM0IsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLHFCQUFxQjtzQkFBN0IsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE9uSW5pdCwgUmVuZGVyZXIyLCBTaW1wbGVDaGFuZ2VzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSdcclxuaW1wb3J0IHsgTnNDb250ZW50IH0gZnJvbSAnLi4vLi4vLi4vLi4vX3NlcnZpY2VzL3dpZGdldC1jb250ZW50Lm1vZGVsJ1xyXG5pbXBvcnQgeyB2aWV3ZXJSb3V0ZUdlbmVyYXRvciB9IGZyb20gJy4uLy4uLy4uLy4uL19zZXJ2aWNlcy92aWV3ZXItcm91dGUtdXRpbCdcclxuaW1wb3J0IHsgTnNBcHBUb2MgfSBmcm9tICcuLi8uLi8uLi8uLi9tb2RlbHMvYXBwLXRvYy5tb2RlbCdcclxuaW1wb3J0IHsgRXZlbnRTZXJ2aWNlLCBXc0V2ZW50cywgQ29uZmlndXJhdGlvbnNTZXJ2aWNlIH0gZnJvbSAnQHN1bmJpcmQtY2IvdXRpbHMtdjInXHJcbmltcG9ydCB7IENlcnRpZmljYXRlRGlhbG9nQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vY2VydGlmaWNhdGUtZGlhbG9nL2NlcnRpZmljYXRlLWRpYWxvZy5jb21wb25lbnQnXHJcbmltcG9ydCB7IE1hdExlZ2FjeURpYWxvZyBhcyBNYXREaWFsb2cgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9sZWdhY3ktZGlhbG9nJ1xyXG5pbXBvcnQgeyBhbmltYXRlLCBzdHlsZSwgdHJhbnNpdGlvbiwgdHJpZ2dlciB9IGZyb20gJ0Bhbmd1bGFyL2FuaW1hdGlvbnMnXHJcbi8qIHRzbGludDpkaXNhYmxlKi9cclxuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJ1xyXG5pbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudCdcclxuaW1wb3J0IHsgQ2VydGlmaWNhdGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vLi4vc2VydmljZXMvY2VydGlmaWNhdGUuc2VydmljZSdcclxuaW1wb3J0IHsgQXBwVG9jU2VydmljZSB9IGZyb20gJy4uLy4uLy4uLy4uL3NlcnZpY2VzL2FwcC10b2Muc2VydmljZSdcclxuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcydcclxuaW1wb3J0IHsgQ29udGVudExhbmd1YWdlU2VydmljZSB9IGZyb20gJ0BzdW5iaXJkLWNiL2NvbnN1bXB0aW9uJ1xyXG5pbXBvcnQgeyBSZXNvdXJjZURvd25sb2FkSGVscGVyU2VydmljZSB9IGZyb20gJy4uLy4uLy4uLy4uL3NlcnZpY2VzL3Jlc291cmNlLWRvd25sb2FkLWhlbHBlci5zZXJ2aWNlJ1xyXG5pbXBvcnQgeyBNYXRMZWdhY3lTbmFja0JhciBhcyBNYXRTbmFja0JhciB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2xlZ2FjeS1zbmFjay1iYXInXHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ3dzLXdpZGdldC1hcHAtdG9jLWNvbnRlbnQtY2FyZC12MicsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2FwcC10b2MtY29udGVudC1jYXJkLXYyLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9hcHAtdG9jLWNvbnRlbnQtY2FyZC12Mi5jb21wb25lbnQuc2NzcyddLFxyXG4gIGFuaW1hdGlvbnM6IFtcclxuICAgIHRyaWdnZXIoJ3BhbmVsSW5PdXQnLCBbXHJcbiAgICAgIHRyYW5zaXRpb24oJ3ZvaWQgPT4gKicsIFtcclxuICAgICAgICBzdHlsZSh7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVkoLTEwJSknLCBvcGFjaXR5OiAnMCcgfSksXHJcbiAgICAgICAgYW5pbWF0ZSgyNTApXHJcbiAgICAgIF0pLFxyXG4gICAgICB0cmFuc2l0aW9uKCcqID0+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, cdr) {
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.cdr = cdr;
40
+ this.content = null;
41
+ this.expandAll = false;
42
+ this.forPreview = false;
43
+ this.componentName = 'toc';
44
+ this.expandActive = true;
45
+ this.hierarchyMapData = {};
46
+ this.batchData = null;
47
+ this.isPreAssessment = false;
48
+ this.baseContentReadData = null;
49
+ this.mlCourse = null;
50
+ this.parentMilestoneLocked = false; // Passed from parent when inside a locked milestone
51
+ this.hasContentStructure = false;
52
+ this.downloadCertificateLoading = false;
53
+ this.enumContentTypes = NsContent.EDisplayContentTypes;
54
+ this.contentStructure = {
55
+ assessment: 0,
56
+ finalTest: 0,
57
+ course: 0,
58
+ handsOn: 0,
59
+ interactiveVideo: 0,
60
+ learningModule: 0,
61
+ other: 0,
62
+ pdf: 0,
63
+ survey: 0,
64
+ podcast: 0,
65
+ practiceTest: 0,
66
+ quiz: 0,
67
+ video: 0,
68
+ webModule: 0,
69
+ webPage: 0,
70
+ youtube: 0,
71
+ interactivecontent: 0,
72
+ offlineSession: 0,
73
+ };
74
+ this.defaultThumbnail = '';
75
+ this.viewChildren = false;
76
+ this.primaryCategory = NsContent.EPrimaryCategory;
77
+ this.pageScrollSubscription = null;
78
+ this.hashmapUpdatedSubscription = null;
79
+ this.achievementLoading = false;
80
+ // Cached computed properties for performance optimization
81
+ this._cachedIsCollection = false;
82
+ this._cachedIsModule = false;
83
+ this._cachedIsResource = false;
84
+ this._cachedIsMilestone = false;
85
+ // IMPORTANT: Default to TRUE (locked) - milestones should be locked until explicitly unlocked
86
+ this._cachedIsMilestoneLocked = true;
87
+ this._cachedIsParentMilestoneLocked = false;
88
+ this._cachedIsContentUnlocked = true;
89
+ this._cachedCheckForCuratedProgram = false;
90
+ this._cachedIsMilestoneAssessment = false;
91
+ this._cachedIsMilestoneAssessmentLocked = false;
92
+ this._cachedResourceLink = { url: '', queryParams: {} };
93
+ this._cachedMilestoneCompletedCount = 0;
94
+ this._cacheInitialized = false;
95
+ }
96
+ ngOnInit() {
97
+ this.evaluateImmediateChildrenStructure();
98
+ this.initializeComputedProperties();
99
+ // this.route.data.subscribe(data => {
100
+ // this.defaultThumbnail = data.configData.data.logos.defaultContent
101
+ // }
102
+ // )
103
+ this.resourceScroll();
104
+ // Subscribe to hashmap updates to recompute cached properties when progress changes
105
+ this.hashmapUpdatedSubscription = this.appTocSvc.hashmapUpdated$.subscribe((update) => {
106
+ if (update && update.hashmap) {
107
+ // IMPORTANT: Update hierarchyMapData with the latest hashmap from the service
108
+ // This ensures the component uses the updated data, not the stale @Input reference
109
+ this.hierarchyMapData = update.hashmap;
110
+ const prevLockState = this._cachedIsMilestoneLocked;
111
+ this.computeAllCachedProperties();
112
+ // Force Angular change detection to update the view
113
+ this.cdr.detectChanges();
114
+ }
115
+ });
116
+ }
117
+ /**
118
+ * Initialize all computed properties once to avoid expensive getter calculations
119
+ * on every change detection cycle
120
+ */
121
+ initializeComputedProperties() {
122
+ this.computeAllCachedProperties();
123
+ }
124
+ /**
125
+ * Compute all cached properties at once for performance optimization
126
+ */
127
+ computeAllCachedProperties() {
128
+ if (!this.content) {
129
+ this._cacheInitialized = false;
130
+ return;
131
+ }
132
+ const contentId = this.content.identifier;
133
+ const hashData = this.hierarchyMapData && this.hierarchyMapData[contentId];
134
+ // Use hashmap data if available for pre-computed values
135
+ if (hashData) {
136
+ this._cachedIsCollection = hashData.isCollection !== undefined ?
137
+ hashData.isCollection : this.content.mimeType === NsContent.EMimeTypes.COLLECTION;
138
+ this._cachedIsModule = hashData.isModule !== undefined ?
139
+ hashData.isModule : this.content.primaryCategory === NsContent.EPrimaryCategory.MODULE;
140
+ this._cachedIsResource = hashData.isResource !== undefined ?
141
+ hashData.isResource : this.computeIsResource();
142
+ this._cachedIsMilestone = hashData.isMilestone !== undefined ?
143
+ hashData.isMilestone : this.computeIsMilestone();
144
+ this._cachedIsMilestoneLocked = hashData.computedIsLocked !== undefined ?
145
+ hashData.computedIsLocked : this.computeIsMilestoneLocked();
146
+ this._cachedIsParentMilestoneLocked = hashData.isParentMilestoneLocked !== undefined ?
147
+ hashData.isParentMilestoneLocked : this.computeIsParentMilestoneLocked();
148
+ }
149
+ else {
150
+ // Fallback to direct computation if hashmap not available
151
+ this._cachedIsCollection = this.content.mimeType === NsContent.EMimeTypes.COLLECTION;
152
+ this._cachedIsModule = this.content.primaryCategory === NsContent.EPrimaryCategory.MODULE;
153
+ this._cachedIsResource = this.computeIsResource();
154
+ this._cachedIsMilestone = this.computeIsMilestone();
155
+ this._cachedIsMilestoneLocked = this.computeIsMilestoneLocked();
156
+ this._cachedIsParentMilestoneLocked = this.computeIsParentMilestoneLocked();
157
+ }
158
+ this._cachedCheckForCuratedProgram = this.computeCheckForCuratedProgram();
159
+ this._cachedIsContentUnlocked = this.computeIsContentUnlocked();
160
+ this._cachedIsMilestoneAssessment = this.computeIsMilestoneAssessment();
161
+ this._cachedIsMilestoneAssessmentLocked = this.computeIsMilestoneAssessmentLocked();
162
+ this._cachedResourceLink = this.computeResourceLink();
163
+ this._cachedMilestoneCompletedCount = this.computeMilestoneCompletedCount();
164
+ this._cacheInitialized = true;
165
+ }
166
+ computeIsResource() {
167
+ if (!this.content)
168
+ return false;
169
+ return (this.content.primaryCategory === NsContent.EPrimaryCategory.RESOURCE ||
170
+ this.content.primaryCategory === NsContent.EPrimaryCategory.PRACTICE_RESOURCE ||
171
+ this.content.primaryCategory === NsContent.EPrimaryCategory.FINAL_ASSESSMENT ||
172
+ this.content.primaryCategory === NsContent.EPrimaryCategory.COMP_ASSESSMENT);
173
+ }
174
+ computeIsMilestone() {
175
+ if (!this.content)
176
+ return false;
177
+ const primaryCat = this.content.primaryCategory;
178
+ const courseCat = this.content.courseCategory;
179
+ return primaryCat === 'Milestone' || courseCat === 'Milestone';
180
+ }
181
+ computeCheckForCuratedProgram() {
182
+ if (this.content && this.content.parent && this.hierarchyMapData && this.hierarchyMapData[this.content.parent]) {
183
+ const parentData = this.hierarchyMapData[this.content.parent];
184
+ return parentData && parentData.primaryCategory === NsContent.EPrimaryCategory.CURATED_PROGRAM &&
185
+ parentData.compatibilityLevel >= 5 &&
186
+ parentData.contextLockingType === NsContent.EContextLockingType.COURSE_ASSESSMENT_ONLY;
187
+ }
188
+ return false;
189
+ }
190
+ computeIsContentUnlocked() {
191
+ if (this._cachedCheckForCuratedProgram) {
192
+ if (this.content && this.content.parent && this.hierarchyMapData && this.hierarchyMapData[this.content.parent]) {
193
+ const parentData = this.hierarchyMapData[this.content.parent];
194
+ let completedLeafNodes = [];
195
+ parentData.leafNodes.forEach((_ele) => {
196
+ if (this.hierarchyMapData && this.hierarchyMapData[_ele]) {
197
+ const childData = this.hierarchyMapData[_ele];
198
+ if (childData && childData.completionStatus === 2) {
199
+ completedLeafNodes.push(childData);
200
+ }
201
+ }
202
+ });
203
+ return completedLeafNodes.length >= parentData.leafNodesCount - 1;
204
+ }
205
+ return false;
206
+ }
207
+ return true;
208
+ }
209
+ computeResourceLink() {
210
+ if (this.content) {
211
+ let mimeType = '';
212
+ if (this.content && this.content.courseCategory === 'Pre Enrolment Assessment' &&
213
+ this.content.mimeType === 'application/vnd.ekstep.content-collection') {
214
+ mimeType = 'application/vnd.sunbird.questionset';
215
+ this.content.mimeType = NsContent.EMimeTypes.FINAL_ASSESSMENT;
216
+ }
217
+ else {
218
+ mimeType = this.content.mimeType;
219
+ }
220
+ const selectedLanguage = this.mlCourse ? this.contentLangSvc.getSelectedLanguage(this.mlCourse) : undefined;
221
+ 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));
222
+ }
223
+ return { url: '', queryParams: {} };
224
+ }
225
+ computeIsMilestoneLocked() {
226
+ // Only apply milestone locking for Learning Pathway content
227
+ if (!this.baseContentReadData || this.baseContentReadData.courseCategory !== 'Learning Pathway') {
228
+ return false;
229
+ }
230
+ if (!this.content) {
231
+ return false;
232
+ }
233
+ // Check if current content is a Milestone
234
+ if (!this._cachedIsMilestone && !this.computeIsMilestone()) {
235
+ return false;
236
+ }
237
+ // Check if hashmap has pre-computed locking status (preferred - computed by service)
238
+ const hashData = this.hierarchyMapData && this.hierarchyMapData[this.content.identifier];
239
+ // CRITICAL: Only use computedIsLocked from hashmap - this is the SINGLE SOURCE OF TRUTH
240
+ // The service computes this value based on pre-assessment/milestone completion
241
+ if (hashData && hashData.computedIsLocked !== undefined) {
242
+ return hashData.computedIsLocked;
243
+ }
244
+ // IMPORTANT: If no computedIsLocked value exists, default to LOCKED
245
+ // This ensures milestones stay locked until the service explicitly unlocks them
246
+ // DO NOT use this.content.isLocked as it may be false by default from API
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 (set by computeMilestoneLockingStatus)
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
+ // CRITICAL: Only check computedIsLocked (computed by service), NOT isLocked (API default)
272
+ // isLocked from API may be false even when milestone should be locked
273
+ if ((parentData.isMilestone || parentData.primaryCategory === 'Milestone' || parentData.courseCategory === 'Milestone') &&
274
+ parentData.computedIsLocked === true) {
275
+ return true;
276
+ }
277
+ currentParentId = parentData.parent;
278
+ }
279
+ else {
280
+ break;
281
+ }
282
+ depth++;
283
+ }
284
+ return false;
285
+ }
286
+ /**
287
+ * Check if current content is a MILESTONE assessment (DIRECT child of a Milestone)
288
+ * IMPORTANT: This should NOT return true for course assessments inside courses within milestones
289
+ * Only assessments that are direct children of milestones should be locked by milestone logic
290
+ */
291
+ computeIsMilestoneAssessment() {
292
+ if (!this.baseContentReadData || this.baseContentReadData.courseCategory !== 'Learning Pathway') {
293
+ return false;
294
+ }
295
+ if (!this.content || !this.hierarchyMapData) {
296
+ return false;
297
+ }
298
+ // Check if this is an assessment type
299
+ // Note: FINAL_ASSESSMENT maps to 'Course Assessment' in the enum, not 'Final Assessment'
300
+ const isAssessment = this.content.primaryCategory === 'Course Assessment' ||
301
+ this.content.primaryCategory === 'Standalone Assessment' ||
302
+ this.content.mimeType === 'application/vnd.sunbird.questionset' ||
303
+ this.content.mimeType === 'application/quiz';
304
+ if (!isAssessment) {
305
+ return false;
306
+ }
307
+ // IMPORTANT: Only return true if the DIRECT parent is a milestone
308
+ // Assessments inside courses (grandchildren of milestones) should NOT be locked by milestone logic
309
+ // They follow their own course's locking rules
310
+ // Get the parent from hashmap (which we fixed to track correct parent-child relationships)
311
+ // or fallback to content.parent if hashmap entry doesn't exist
312
+ const contentHashData = this.hierarchyMapData[this.content.identifier];
313
+ const parentId = contentHashData?.parent || this.content.parent;
314
+ if (parentId && this.hierarchyMapData[parentId]) {
315
+ const parentData = this.hierarchyMapData[parentId];
316
+ // Check if DIRECT parent is a milestone - ONLY this case
317
+ const isParentMilestone = parentData.isMilestone ||
318
+ parentData.primaryCategory === 'Milestone' ||
319
+ parentData.courseCategory === 'Milestone';
320
+ if (isParentMilestone) {
321
+ return true;
322
+ }
323
+ // DO NOT check grandparent - course assessments inside courses within milestones
324
+ // should NOT be treated as milestone assessments
325
+ return false;
326
+ }
327
+ return false;
328
+ }
329
+ /**
330
+ * Check if milestone assessment should be locked
331
+ * Assessment is locked if:
332
+ * 1. It's an assessment that is a DIRECT child of a milestone
333
+ * 2. The parent milestone is unlocked (otherwise handled by parent milestone lock)
334
+ * 3. NOT all mandatory courses in the same milestone are completed
335
+ */
336
+ computeIsMilestoneAssessmentLocked() {
337
+ // CRITICAL: Only apply milestone assessment locking for Learning Pathway content
338
+ // Regular courses should NEVER have their assessments locked by milestone logic
339
+ if (!this.baseContentReadData || this.baseContentReadData.courseCategory !== 'Learning Pathway') {
340
+ return false;
341
+ }
342
+ // Only apply to assessments that are DIRECT children of milestones
343
+ const isMilestoneAssessment = this._cachedIsMilestoneAssessment || this.computeIsMilestoneAssessment();
344
+ if (!isMilestoneAssessment) {
345
+ return false;
346
+ }
347
+ // Check if hashmap has pre-computed assessment locking status
348
+ const hashData = this.hierarchyMapData && this.hierarchyMapData[this.content?.identifier || ''];
349
+ if (hashData && hashData.isAssessmentLocked !== undefined) {
350
+ return hashData.isAssessmentLocked;
351
+ }
352
+ // If already completed, don't lock
353
+ if (this.content && (this.content.completionStatus === 2 ||
354
+ (this.content.completionPercentage && this.content.completionPercentage >= 100))) {
355
+ return false;
356
+ }
357
+ // For milestone assessments, the parent IS the milestone (verified by computeIsMilestoneAssessment)
358
+ // Use hashmap's parent which has correct parent-child relationships
359
+ const contentHashData = this.hierarchyMapData && this.hierarchyMapData[this.content?.identifier || ''];
360
+ const milestoneId = contentHashData?.parent || this.content?.parent;
361
+ if (!milestoneId || !this.hierarchyMapData) {
362
+ return false;
363
+ }
364
+ const milestone = this.hierarchyMapData[milestoneId];
365
+ if (!milestone) {
366
+ return false;
367
+ }
368
+ // If the parent milestone itself is locked, don't add additional locking
369
+ // (the parent lock will handle it)
370
+ if (milestone.computedIsLocked || milestone.isLocked) {
371
+ return false;
372
+ }
373
+ // Check if all mandatory COURSES in the milestone are completed
374
+ // Note: Only checking courses that are direct children of the milestone
375
+ let mandatoryCount = 0;
376
+ let completedMandatoryCount = 0;
377
+ for (const key of Object.keys(this.hierarchyMapData)) {
378
+ const item = this.hierarchyMapData[key];
379
+ // Only check items that are direct children of this milestone
380
+ if (item.parent !== milestoneId)
381
+ continue;
382
+ // Only count courses (not assessments, not other types)
383
+ if (item.primaryCategory !== 'Course' && !item.isCollection)
384
+ continue;
385
+ // Skip if this is an assessment
386
+ const isItemAssessment = item.primaryCategory === 'Course Assessment' ||
387
+ item.primaryCategory === 'Final Assessment' ||
388
+ item.primaryCategory === 'Standalone Assessment' ||
389
+ item.mimeType === 'application/vnd.sunbird.questionset';
390
+ if (isItemAssessment)
391
+ continue;
392
+ // By default, courses are mandatory unless explicitly marked as optional
393
+ if (item.isMandatory !== false) {
394
+ mandatoryCount++;
395
+ const isCompleted = item.completionStatus === 2 || item.status === 2 ||
396
+ item.completionPercentage >= 100 || item.progress >= 100;
397
+ if (isCompleted) {
398
+ completedMandatoryCount++;
399
+ }
400
+ }
401
+ }
402
+ // If there are no mandatory courses, assessment is unlocked
403
+ if (mandatoryCount === 0) {
404
+ return false;
405
+ }
406
+ // Lock assessment if not all mandatory courses are completed
407
+ const allMandatoryComplete = completedMandatoryCount >= mandatoryCount;
408
+ return !allMandatoryComplete;
409
+ }
410
+ // FOR RIGHT SIDE RESOURCE SCROLL ON TOC PAGE
411
+ resourceScroll() {
412
+ this.pageScrollSubscription = this.appTocSvc.updatePageScroll.subscribe((value) => {
413
+ if (value) {
414
+ setTimeout(() => {
415
+ this.scrollView();
416
+ }, 700);
417
+ }
418
+ });
419
+ }
420
+ // TO UPDATE RESOURCE BEHAVOUR SUBJECT FOR RESOURCE SCROLL
421
+ changeResource() {
422
+ this.appTocSvc.getPageScroll.next(true);
423
+ }
424
+ ngOnChanges(changes) {
425
+ let shouldRecomputeCache = false;
426
+ for (const property in changes) {
427
+ if (property === 'expandAll') {
428
+ this.viewChildren = this.expandAll;
429
+ }
430
+ if (property === 'pathSet' && changes['pathSet']) {
431
+ let currentValue = changes['pathSet'].currentValue;
432
+ let previousValue = changes['pathSet'].previousValue;
433
+ if (currentValue && previousValue) {
434
+ const eqSet = (xs, ys) => xs.size === ys.size &&
435
+ [...xs].every((x) => ys.has(x));
436
+ if (!eqSet(previousValue, currentValue)) { }
437
+ }
438
+ // if(previousValue === undefined){
439
+ // setTimeout(()=>{
440
+ // },700)
441
+ // }
442
+ }
443
+ // this.appTocSvc.getPageScroll.next(true)
444
+ if (property === 'hierarchyMapData') {
445
+ if (_.isEmpty(changes['hierarchyMapData'].currentValue)) {
446
+ // this.loadingOverallPRogress = true
447
+ }
448
+ else {
449
+ if (this.content) {
450
+ this.updateChildParentMap(this.content.identifier);
451
+ }
452
+ shouldRecomputeCache = true;
453
+ }
454
+ }
455
+ // Recompute cache when critical inputs change
456
+ if (property === 'content' || property === 'baseContentReadData' ||
457
+ property === 'batchId' || property === 'forPreview' ||
458
+ property === 'parentMilestoneLocked' || property === 'mlCourse') {
459
+ shouldRecomputeCache = true;
460
+ }
461
+ }
462
+ // Recompute all cached properties if needed
463
+ if (shouldRecomputeCache) {
464
+ this.computeAllCachedProperties();
465
+ }
466
+ }
467
+ check(content) {
468
+ if (this.expandActive) {
469
+ content.viewChildren = this.pathSet && this.pathSet.has(content.identifier) || content.viewChildren;
470
+ }
471
+ return content.viewChildren;
472
+ }
473
+ get isCollection() {
474
+ if (this._cacheInitialized) {
475
+ return this._cachedIsCollection;
476
+ }
477
+ if (this.content) {
478
+ return this.content.mimeType === NsContent.EMimeTypes.COLLECTION;
479
+ }
480
+ return false;
481
+ }
482
+ get isModule() {
483
+ if (this._cacheInitialized) {
484
+ return this._cachedIsModule;
485
+ }
486
+ if (this.content) {
487
+ return this.content.primaryCategory === NsContent.EPrimaryCategory.MODULE;
488
+ }
489
+ return false;
490
+ }
491
+ checkModule(content) {
492
+ if (content) {
493
+ return content.primaryCategory === NsContent.EPrimaryCategory.MODULE;
494
+ }
495
+ return false;
496
+ }
497
+ checkIsModule(content) {
498
+ if (content) {
499
+ return content.primaryCategory === NsContent.EPrimaryCategory.MODULE;
500
+ }
501
+ return false;
502
+ }
503
+ get isBatchInProgess() {
504
+ if (this.batchData && (this.batchData.content && this.batchData.content.length) && this.batchData.enrolled) {
505
+ const batchData = this.batchData.content[0];
506
+ if (batchData && batchData.endDate) {
507
+ const now = moment().format('YYYY-MM-DD');
508
+ const startDate = moment(batchData.startDate).format('YYYY-MM-DD');
509
+ const endDate = batchData.endDate ? moment(batchData.endDate).format('YYYY-MM-DD') : now;
510
+ return (
511
+ // batch.status &&
512
+ moment(startDate).isSameOrBefore(now)
513
+ && moment(endDate).isSameOrAfter(now));
514
+ }
515
+ return true;
516
+ }
517
+ return false;
518
+ }
519
+ get isResource() {
520
+ if (this._cacheInitialized) {
521
+ return this._cachedIsResource;
522
+ }
523
+ return this.computeIsResource();
524
+ }
525
+ get resourceLink() {
526
+ if (this._cacheInitialized) {
527
+ return this._cachedResourceLink;
528
+ }
529
+ return this.computeResourceLink();
530
+ }
531
+ progressColor() {
532
+ // if (this.currentProgress <= 30) {
533
+ // return '#D13924'
534
+ // } if (this.currentProgress > 30 && this.currentProgress <= 70) {
535
+ // return '#E99E38'
536
+ // }
537
+ // if (this.currentProgress > 70 && this.currentProgress <= 100) {
538
+ // return '#1D8923'
539
+ // }
540
+ return '#1D8923';
541
+ }
542
+ progressColor2() {
543
+ return '#f27d00';
544
+ }
545
+ evaluateImmediateChildrenStructure() {
546
+ if (this.content && this.content.children && this.content.children.length) {
547
+ this.content.children.forEach((child) => {
548
+ if (child.primaryCategory === NsContent.EPrimaryCategory.COURSE) {
549
+ this.contentStructure.course += 1;
550
+ }
551
+ else if (child.primaryCategory === NsContent.EPrimaryCategory.KNOWLEDGE_ARTIFACT) {
552
+ this.contentStructure.other += 1;
553
+ }
554
+ else if (child.primaryCategory === NsContent.EPrimaryCategory.MODULE) {
555
+ this.contentStructure.learningModule += 1;
556
+ }
557
+ else if (child.primaryCategory === NsContent.EPrimaryCategory.OFFLINE_SESSION) {
558
+ this.contentStructure.offlineSession += 1;
559
+ }
560
+ else if (child.primaryCategory === NsContent.EPrimaryCategory.RESOURCE) {
561
+ switch (child.mimeType) {
562
+ case NsContent.EMimeTypes.HANDS_ON:
563
+ this.contentStructure.handsOn += 1;
564
+ break;
565
+ case NsContent.EMimeTypes.MP3:
566
+ this.contentStructure.podcast += 1;
567
+ break;
568
+ case NsContent.EMimeTypes.MP4:
569
+ case NsContent.EMimeTypes.M3U8:
570
+ this.contentStructure.video += 1;
571
+ break;
572
+ case NsContent.EMimeTypes.INTERACTION:
573
+ this.contentStructure.interactiveVideo += 1;
574
+ break;
575
+ case NsContent.EMimeTypes.PDF:
576
+ this.contentStructure.pdf += 1;
577
+ break;
578
+ case NsContent.EMimeTypes.OFFLINE_SESSION:
579
+ this.contentStructure.offlineSession += 1;
580
+ break;
581
+ case NsContent.EMimeTypes.SURVEY:
582
+ this.contentStructure.survey += 1;
583
+ break;
584
+ case NsContent.EMimeTypes.HTML:
585
+ this.contentStructure.webPage += 1;
586
+ break;
587
+ case NsContent.EMimeTypes.QUIZ:
588
+ if (child.resourceType === 'Assessment') {
589
+ this.contentStructure.assessment += 1;
590
+ }
591
+ else {
592
+ this.contentStructure.quiz += 1;
593
+ }
594
+ break;
595
+ case NsContent.EMimeTypes.PRACTICE_RESOURCE:
596
+ // case NsContent.EMimeTypes.FINAL_ASSESSMENT:
597
+ // case NsContent.EMimeTypes.PRACTICE_RESOURCE:
598
+ this.contentStructure.practiceTest += 1;
599
+ break;
600
+ case NsContent.EMimeTypes.WEB_MODULE:
601
+ this.contentStructure.webModule += 1;
602
+ break;
603
+ case NsContent.EMimeTypes.YOUTUBE:
604
+ this.contentStructure.youtube += 1;
605
+ break;
606
+ default:
607
+ this.contentStructure.other += 1;
608
+ break;
609
+ }
610
+ }
611
+ });
612
+ }
613
+ for (const key in this.contentStructure) {
614
+ if (this.contentStructure[key] > 0) {
615
+ this.hasContentStructure = true;
616
+ }
617
+ }
618
+ }
619
+ get contextPath() {
620
+ return {
621
+ contextId: this.rootId,
622
+ contextPath: this.rootContentType,
623
+ batchId: this.batchId,
624
+ };
625
+ }
626
+ contentTrackBy(_index, content) {
627
+ if (!content) {
628
+ return null;
629
+ }
630
+ return content.identifier;
631
+ }
632
+ raiseTelemetry() {
633
+ // if (this.forPreview) { return }
634
+ if (this.content) {
635
+ this.events.raiseInteractTelemetry({
636
+ type: 'click',
637
+ subType: `card-tocContentCard`,
638
+ // id: this.content.identifier || '',
639
+ }, {
640
+ // contentId: this.content.identifier || '',
641
+ // contentType: this.content.primaryCategory,
642
+ id: this.content.identifier || '',
643
+ type: this.content.primaryCategory,
644
+ rollup: {
645
+ l1: this.rootId || '',
646
+ },
647
+ ver: `${this.content.version}${''}`,
648
+ }, {
649
+ pageIdExt: `${_.camelCase(this.content.primaryCategory)}-card`,
650
+ module: _.camelCase(this.content.primaryCategory),
651
+ });
652
+ }
653
+ }
654
+ get isAllowed() {
655
+ if (this.content) {
656
+ return !(NsContent.UN_SUPPORTED_DATA_TYPES_FOR_NON_BATCH_USERS.indexOf(this.content.mimeType) >= 0);
657
+ }
658
+ return false;
659
+ }
660
+ get isEnabled() {
661
+ return true;
662
+ }
663
+ get isEnrolled() {
664
+ // Check both batchId and batchData.enrolled to support Learning Pathways
665
+ // where batchId might not be directly set but user is enrolled in courses within the pathway
666
+ return this.batchId ? true : (this.batchData?.enrolled || false);
667
+ }
668
+ updateChildParentMap(identifier) {
669
+ if (this.hierarchyMapData && this.hierarchyMapData[identifier]) {
670
+ let localContentData = this.hierarchyMapData[identifier];
671
+ if (!(localContentData.primaryCategory === NsContent.EPrimaryCategory.RESOURCE
672
+ || localContentData.primaryCategory === NsContent.EPrimaryCategory.PRACTICE_RESOURCE
673
+ || localContentData.primaryCategory === NsContent.EPrimaryCategory.FINAL_ASSESSMENT
674
+ || localContentData.primaryCategory === NsContent.EPrimaryCategory.COMP_ASSESSMENT)) {
675
+ // real percent logic
676
+ // const total = localContentData.leafNodes.reduce((sum: number, childId: string) => {
677
+ // return sum + Number(this.hierarchyMapData[childId].completionPercentage || 0)
678
+ // }, 0)
679
+ // if(total > 0) {
680
+ // this.hierarchyMapData[identifier]['completionPercentage'] = total / _.toInteger(_.get(this.hierarchyMapData[identifier], 'leafNodesCount'))
681
+ // }
682
+ if (localContentData.primaryCategory === NsContent.EPrimaryCategory.MODULE) {
683
+ this.hierarchyMapData[identifier]['duration'] = this.hierarchyMapData[identifier].leafNodes.reduce((sum, childID) => {
684
+ if (this.hierarchyMapData && this.hierarchyMapData[childID]) {
685
+ return sum + Number(this.hierarchyMapData[childID].duration || this.hierarchyMapData[childID].expectedDuration || 0);
686
+ }
687
+ }, 0);
688
+ }
689
+ // tslint:disable
690
+ const completedItems = _.filter(this.hierarchyMapData[identifier].leafNodes, r => (this.hierarchyMapData[r] && (this.hierarchyMapData[r].completionStatus === 2 || this.hierarchyMapData[r].completionPercentage === 100)));
691
+ const totalCount = _.toInteger(_.get(this.hierarchyMapData[identifier], 'leafNodesCount')) || 1;
692
+ this.hierarchyMapData[identifier]['completionPercentage'] = Number(((completedItems.length / totalCount) * 100).toFixed());
693
+ this.hierarchyMapData[identifier]['completionStatus'] = (this.hierarchyMapData[identifier].completionPercentage >= 100) ? 2 : 1;
694
+ }
695
+ return this.hierarchyMapData[identifier];
696
+ }
697
+ return '';
698
+ }
699
+ getCompletionPercentage(identifier) {
700
+ // const item = this.updateChildParentMap(identifier)
701
+ let percent = this.hierarchyMapData && this.hierarchyMapData[identifier] && this.hierarchyMapData[identifier].completionPercentage || 0;
702
+ return this.roundIfDecimal(percent);
703
+ }
704
+ roundIfDecimal(value) {
705
+ if (!Number.isInteger(value)) {
706
+ return parseFloat(value.toFixed(2));
707
+ }
708
+ return value;
709
+ }
710
+ getCompletionStatus(identifier) {
711
+ // const item = this.updateChildParentMap(identifier)
712
+ return this.hierarchyMapData && this.hierarchyMapData[identifier] && this.hierarchyMapData[identifier].completionStatus;
713
+ }
714
+ /**
715
+ * Check if milestone is complete based on mandatory content and assessment completion
716
+ * Returns true only when:
717
+ * 1. All mandatory content is completed (or no mandatory content exists)
718
+ * 2. Milestone assessment is completed (or no assessment exists)
719
+ */
720
+ isMilestoneComplete(identifier) {
721
+ if (!this.hierarchyMapData) {
722
+ return false;
723
+ }
724
+ const milestoneData = this.hierarchyMapData[identifier];
725
+ if (!milestoneData) {
726
+ return false;
727
+ }
728
+ // Check if all mandatory content AND milestone assessment are completed
729
+ let hasMandatoryContent = false;
730
+ let allMandatoryComplete = true;
731
+ let hasMilestoneAssessment = false;
732
+ let milestoneAssessmentComplete = false;
733
+ // Check all direct children of the milestone
734
+ for (const key of Object.keys(this.hierarchyMapData)) {
735
+ const item = this.hierarchyMapData[key];
736
+ // Only check direct children
737
+ if (item.parent !== identifier)
738
+ continue;
739
+ // Check if this is the milestone assessment
740
+ const isAssessment = item.primaryCategory === 'Course Assessment' ||
741
+ item.primaryCategory === 'Final Assessment' ||
742
+ item.primaryCategory === 'Standalone Assessment';
743
+ if (isAssessment) {
744
+ hasMilestoneAssessment = true;
745
+ const isCompleted = item.completionStatus === 2 || item.status === 2 ||
746
+ item.completionPercentage >= 100 || item.progress >= 100;
747
+ if (isCompleted) {
748
+ milestoneAssessmentComplete = true;
749
+ }
750
+ continue; // Skip to next item
751
+ }
752
+ // Check if this is mandatory content (courses/collections)
753
+ if (item.primaryCategory === 'Course' || item.isCollection) {
754
+ const isMandatory = item.isMandatory !== false; // Default is mandatory
755
+ if (isMandatory) {
756
+ hasMandatoryContent = true;
757
+ const isCompleted = item.completionStatus === 2 || item.status === 2 ||
758
+ item.completionPercentage >= 100 || item.progress >= 100;
759
+ if (!isCompleted) {
760
+ allMandatoryComplete = false;
761
+ }
762
+ }
763
+ }
764
+ }
765
+ // Milestone is complete when:
766
+ // 1. All mandatory content is completed (or no mandatory content exists)
767
+ // 2. Milestone assessment is completed (or no assessment exists)
768
+ const mandatoryCheck = !hasMandatoryContent || allMandatoryComplete;
769
+ const assessmentCheck = !hasMilestoneAssessment || milestoneAssessmentComplete;
770
+ return mandatoryCheck && assessmentCheck;
771
+ }
772
+ openCertificateDialog(certData) {
773
+ const cet = certData;
774
+ this.dialog.open(CertificateDialogComponent, {
775
+ // height: '400px',
776
+ width: '1300px',
777
+ data: { cet },
778
+ // panelClass: 'custom-dialog-container',
779
+ });
780
+ }
781
+ scrollView() {
782
+ try {
783
+ let errorField = this.renderer.selectRootElement('.resource-container .resource-active');
784
+ if (errorField) {
785
+ errorField.scrollIntoView({ behavior: "smooth", block: "start", inline: "nearest" });
786
+ }
787
+ if (this.componentName === 'toc') {
788
+ if (errorField) {
789
+ const rect = errorField.getBoundingClientRect();
790
+ if (rect.top - 420 > 0) {
791
+ window.scroll(420, rect.top - 148);
792
+ }
793
+ }
794
+ }
795
+ setTimeout(() => {
796
+ this.appTocSvc.getPageScroll.next(false);
797
+ }, 700);
798
+ // else {
799
+ // errorField.scrollIntoView({ behavior: "smooth", block: "start", inline: "nearest" });
800
+ // const rect = errorField.getBoundingClientRect();
801
+ // errorField.scroll(0,rect.top-56)
802
+ // }
803
+ }
804
+ catch (err) {
805
+ }
806
+ }
807
+ downloadCertificate(certificateData) {
808
+ this.events.raiseInteractTelemetry({
809
+ type: WsEvents.EnumInteractTypes.CLICK,
810
+ id: 'view-certificate',
811
+ subType: WsEvents.EnumInteractSubTypes.CERTIFICATE,
812
+ }, {
813
+ id: certificateData,
814
+ type: WsEvents.EnumInteractSubTypes.CERTIFICATE,
815
+ });
816
+ if (certificateData) {
817
+ this.downloadCertificateLoading = true;
818
+ let certData = certificateData || certificateData.identifier;
819
+ this.certificateService.downloadCertificate_v3(certData).subscribe((res) => {
820
+ this.downloadCertificateLoading = false;
821
+ const cet = res.result.printUri;
822
+ this.dialog.open(CertificateDialogComponent, {
823
+ width: '1300px',
824
+ data: { cet, certId: certData },
825
+ });
826
+ });
827
+ }
828
+ else {
829
+ this.downloadCertificateLoading = false;
830
+ }
831
+ }
832
+ ngOnDestroy() {
833
+ if (this.hashmapUpdatedSubscription) {
834
+ this.hashmapUpdatedSubscription.unsubscribe();
835
+ }
836
+ if (this.pageScrollSubscription) {
837
+ this.pageScrollSubscription.unsubscribe();
838
+ }
839
+ }
840
+ get checkForCuratedProgram() {
841
+ if (this._cacheInitialized) {
842
+ return this._cachedCheckForCuratedProgram;
843
+ }
844
+ return this.computeCheckForCuratedProgram();
845
+ }
846
+ get isContentUnlocked() {
847
+ if (this._cacheInitialized) {
848
+ return this._cachedIsContentUnlocked;
849
+ }
850
+ return this.computeIsContentUnlocked();
851
+ }
852
+ get isParentMilestoneLocked() {
853
+ if (this._cacheInitialized) {
854
+ return this._cachedIsParentMilestoneLocked;
855
+ }
856
+ return this.computeIsParentMilestoneLocked();
857
+ }
858
+ get isMilestoneLocked() {
859
+ if (this._cacheInitialized) {
860
+ return this._cachedIsMilestoneLocked;
861
+ }
862
+ return this.computeIsMilestoneLocked();
863
+ }
864
+ get isMilestoneAssessment() {
865
+ if (this._cacheInitialized) {
866
+ return this._cachedIsMilestoneAssessment;
867
+ }
868
+ return this.computeIsMilestoneAssessment();
869
+ }
870
+ get isMilestoneAssessmentLocked() {
871
+ if (this._cacheInitialized) {
872
+ return this._cachedIsMilestoneAssessmentLocked;
873
+ }
874
+ return this.computeIsMilestoneAssessmentLocked();
875
+ }
876
+ /**
877
+ * Check if a milestone's mandatory courses and assessment are completed.
878
+ * Looks at the content hierarchy to find children of the milestone.
879
+ */
880
+ checkMilestoneContentCompletion(milestoneId) {
881
+ if (!this.baseContentReadData || !this.baseContentReadData.children || !this.hierarchyMapData) {
882
+ // Fallback: Try to find assessment completion in hashmap for this milestone
883
+ return this.checkMilestoneAssessmentCompletion(milestoneId);
884
+ }
885
+ // Find the milestone in the content hierarchy
886
+ const milestoneContent = this.findContentInHierarchy(this.baseContentReadData, milestoneId);
887
+ if (!milestoneContent || !milestoneContent.children) {
888
+ return this.checkMilestoneAssessmentCompletion(milestoneId);
889
+ }
890
+ // Check all mandatory courses and assessments
891
+ let allMandatoryComplete = true;
892
+ let hasAssessment = false;
893
+ let assessmentComplete = false;
894
+ milestoneContent.children.forEach((child) => {
895
+ const childData = this.hierarchyMapData[child.identifier];
896
+ const isAssessment = child.primaryCategory === 'Course Assessment' ||
897
+ child.courseCategory === 'Course Assessment' ||
898
+ child.primaryCategory === 'Final Assessment';
899
+ const isMandatory = child.mandatory === true || child.optionalReading !== true;
900
+ if (isAssessment) {
901
+ hasAssessment = true;
902
+ if (childData && (childData.completionStatus === 2 || childData.completionPercentage >= 100)) {
903
+ assessmentComplete = true;
904
+ }
905
+ }
906
+ else if (isMandatory) {
907
+ // Check if mandatory content is completed
908
+ if (!childData || (childData.completionStatus !== 2 && childData.completionPercentage < 100)) {
909
+ allMandatoryComplete = false;
910
+ }
911
+ }
912
+ });
913
+ // Milestone is complete if assessment is complete (mandatory courses optional based on requirements)
914
+ return hasAssessment ? assessmentComplete : allMandatoryComplete;
915
+ }
916
+ /**
917
+ * Fallback: Check if enough assessments are completed to unlock this milestone.
918
+ * For milestone at index N, we need at least N completed assessments.
919
+ * E.g., For M2 (index 1), we need 1 completed assessment (M1's assessment)
920
+ * For M3 (index 2), we need 2 completed assessments (M1's and M2's)
921
+ */
922
+ checkMilestoneAssessmentCompletion(milestoneId) {
923
+ if (!this.hierarchyMapData) {
924
+ return false;
925
+ }
926
+ // Extract milestone number from ID (M1 -> 1, M2 -> 2, etc.)
927
+ const milestoneNum = parseInt(milestoneId.replace(/\D/g, '')) || 0;
928
+ const requiredCompletedAssessments = milestoneNum - 1; // For M2, need 1; for M3, need 2
929
+ if (requiredCompletedAssessments <= 0) {
930
+ return true; // First milestone, no requirements
931
+ }
932
+ // Count completed Course Assessments that are INSIDE milestones (have a parent)
933
+ // Exclude pre-enrollment assessments at the root level (no parent or parent is Learning Pathway)
934
+ let completedMilestoneAssessmentCount = 0;
935
+ const learningPathwayId = this.baseContentReadData?.identifier;
936
+ for (const key of Object.keys(this.hierarchyMapData)) {
937
+ const item = this.hierarchyMapData[key];
938
+ // Check if it's a completed Course Assessment
939
+ if ((item.primaryCategory === 'Course Assessment' || item.courseCategory === 'Course Assessment') &&
940
+ (item.completionStatus === 2 || item.completionPercentage >= 100)) {
941
+ // Check if this assessment has a parent (meaning it's inside a course/milestone, not at root level)
942
+ // Also exclude if parent is the Learning Pathway itself (pre-enrollment assessment)
943
+ const hasParent = item.parent && item.parent !== learningPathwayId;
944
+ if (hasParent) {
945
+ completedMilestoneAssessmentCount++;
946
+ }
947
+ }
948
+ }
949
+ // If we have enough completed milestone assessments, unlock this milestone
950
+ return completedMilestoneAssessmentCount >= requiredCompletedAssessments;
951
+ }
952
+ findContentInHierarchy(content, identifier) {
953
+ if (!content)
954
+ return null;
955
+ if (content.identifier === identifier)
956
+ return content;
957
+ if (content.children) {
958
+ for (const child of content.children) {
959
+ const found = this.findContentInHierarchy(child, identifier);
960
+ if (found)
961
+ return found;
962
+ }
963
+ }
964
+ return null;
965
+ }
966
+ get computedQueryParams() {
967
+ if (this.isAllowed && !this.forPreview && this.isEnabled) {
968
+ return {
969
+ ...this.resourceLink.queryParams,
970
+ preAssessment: 'true'
971
+ };
972
+ }
973
+ return null;
974
+ }
975
+ get isMilestone() {
976
+ if (this._cacheInitialized) {
977
+ return this._cachedIsMilestone;
978
+ }
979
+ return this.computeIsMilestone();
980
+ }
981
+ getMilestoneCompletedCount() {
982
+ if (this._cacheInitialized) {
983
+ return this._cachedMilestoneCompletedCount;
984
+ }
985
+ return this.computeMilestoneCompletedCount();
986
+ }
987
+ computeMilestoneCompletedCount() {
988
+ if (!this.content || !this.hierarchyMapData) {
989
+ return 0;
990
+ }
991
+ const milestoneData = this.hierarchyMapData[this.content.identifier];
992
+ if (!milestoneData || !milestoneData.leafNodes) {
993
+ return 0;
994
+ }
995
+ let completedCount = 0;
996
+ milestoneData.leafNodes.forEach((leafId) => {
997
+ const leafData = this.hierarchyMapData[leafId];
998
+ if (leafData) {
999
+ // CRITICAL: Check multiple completion indicators
1000
+ const isCompleted = leafData.completionStatus === 2 ||
1001
+ leafData.status === 2 ||
1002
+ (leafData.completionPercentage && leafData.completionPercentage >= 100) ||
1003
+ (leafData.progress && leafData.progress >= 100);
1004
+ if (isCompleted) {
1005
+ completedCount++;
1006
+ }
1007
+ }
1008
+ });
1009
+ return completedCount;
1010
+ }
1011
+ /**
1012
+ * Get unlock criteria message for locked milestones
1013
+ */
1014
+ getMilestoneUnlockMessage() {
1015
+ if (!this.content || !this.hierarchyMapData) {
1016
+ return '';
1017
+ }
1018
+ const milestoneData = this.hierarchyMapData[this.content.identifier];
1019
+ if (!milestoneData) {
1020
+ return '';
1021
+ }
1022
+ // Check if hashmap has pre-computed unlock message
1023
+ if (milestoneData.unlockMessage) {
1024
+ return milestoneData.unlockMessage;
1025
+ }
1026
+ const milestoneIndex = milestoneData.milestoneIndex;
1027
+ // Milestone 1 requires pre-assessment completion
1028
+ if (milestoneIndex === 0) {
1029
+ return 'Complete the preliminary assessment to unlock this milestone';
1030
+ }
1031
+ // Other milestones require previous milestone completion
1032
+ return `Complete all mandatory content and assessment in Milestone ${milestoneIndex} to unlock this milestone`;
1033
+ }
1034
+ /**
1035
+ * Get lock message for content inside locked milestones
1036
+ */
1037
+ getParentMilestoneLockMessage() {
1038
+ if (!this.isParentMilestoneLocked) {
1039
+ return '';
1040
+ }
1041
+ return 'This content is locked. Complete previous milestone to view this content.';
1042
+ }
1043
+ /**
1044
+ * Get lock message for milestone assessments
1045
+ */
1046
+ getAssessmentLockMessage() {
1047
+ if (!this.content || !this.hierarchyMapData) {
1048
+ return '';
1049
+ }
1050
+ const hashData = this.hierarchyMapData[this.content.identifier];
1051
+ // Check if hashmap has pre-computed assessment lock message
1052
+ if (hashData && hashData.assessmentLockMessage) {
1053
+ return hashData.assessmentLockMessage;
1054
+ }
1055
+ if (this.isMilestoneAssessmentLocked) {
1056
+ return 'This content is locked. Complete all mandatory items to unlock the assessment.';
1057
+ }
1058
+ return '';
1059
+ }
1060
+ shouldShowDownloadButton(content) {
1061
+ if (!content) {
1062
+ return false;
1063
+ }
1064
+ // Check if content has an artifact URL (downloadable resource)
1065
+ if (!content.artifactUrl) {
1066
+ return false;
1067
+ }
1068
+ // Check if base content resource category includes "Case Study"
1069
+ if (!this.baseContentReadData?.courseCategory ||
1070
+ this.baseContentReadData.courseCategory !== NsContent.ECourseCategory.CASE_STUDY) {
1071
+ return false;
1072
+ }
1073
+ //for public scenario check if its player plage then only enable download
1074
+ if (this.forPreview && !window.location.href.includes('/viewer/')) {
1075
+ return false;
1076
+ }
1077
+ // for logged in user check if user enrolled then only allow download
1078
+ if (!this.forPreview && !this.isEnrolled) {
1079
+ return false;
1080
+ }
1081
+ // Define downloadable MIME types
1082
+ const downloadableMimeTypes = [
1083
+ NsContent.EMimeTypes.PDF
1084
+ ];
1085
+ return downloadableMimeTypes.includes(content.mimeType);
1086
+ }
1087
+ downloadContent(content, event) {
1088
+ if (event) {
1089
+ event.preventDefault();
1090
+ event.stopPropagation();
1091
+ }
1092
+ const pageId = `app/toc/pageId/${content.identifier}`;
1093
+ this.resourceDownloadHelperSvc.downloadPDF(content, pageId);
1094
+ }
1095
+ /**
1096
+ * View milestone achievement - calls the achievement API and shows the result
1097
+ */
1098
+ viewMilestoneAchievement(event, mileStoneData) {
1099
+ if (event) {
1100
+ event.preventDefault();
1101
+ event.stopPropagation();
1102
+ }
1103
+ if (!this.content || !this.batchId || this.achievementLoading) {
1104
+ return;
1105
+ }
1106
+ // Get user ID from ConfigurationsService
1107
+ const userId = this.configSvc?.userProfile?.userId;
1108
+ if (!userId) {
1109
+ return;
1110
+ }
1111
+ // Extract milestone ID (e.g., "m1", "m2") from the content name or index
1112
+ // Try to get milestone number from the index or extract from content
1113
+ let milestoneId = 'm' + (this.index - 1); // index is typically 1-based, milestones are 0-based
1114
+ // If content name contains milestone number, extract it
1115
+ if (this.content.name) {
1116
+ milestoneId = mileStoneData?.identifier;
1117
+ }
1118
+ const courseId = this.baseContentReadData?.identifier || this.rootId;
1119
+ this.achievementLoading = true;
1120
+ this.appTocSvc.generateMilestoneAchievement(userId, courseId, this.batchId, milestoneId).subscribe({
1121
+ next: (response) => {
1122
+ this.achievementLoading = false;
1123
+ // Show achievement dialog or handle response
1124
+ if (response && response.result) {
1125
+ // Open a dialog to show the achievement
1126
+ this.dialog.open(CertificateDialogComponent, {
1127
+ width: '1300px',
1128
+ data: {
1129
+ cet: response.result.printUri || response.result.svgData,
1130
+ certId: response?.result?.identifier || milestoneId,
1131
+ isAchievement: true
1132
+ },
1133
+ });
1134
+ }
1135
+ },
1136
+ error: (error) => {
1137
+ this.achievementLoading = false;
1138
+ // Show error message in snackbar
1139
+ const errorMessage = error?.error?.result?.message || error?.message || 'Failed to generate achievement';
1140
+ this.snackBar.open(errorMessage, 'Close', {
1141
+ duration: 5000,
1142
+ horizontalPosition: 'center',
1143
+ verticalPosition: 'bottom',
1144
+ panelClass: ['error-snackbar']
1145
+ });
1146
+ }
1147
+ });
1148
+ }
1149
+ /**
1150
+ * Check if text is truncated (has ellipsis) - for single line text
1151
+ * @param element The HTMLElement to check
1152
+ * @returns true if text is truncated, false otherwise
1153
+ */
1154
+ isTextTruncated(element) {
1155
+ if (!element)
1156
+ return false;
1157
+ return element.offsetWidth < element.scrollWidth;
1158
+ }
1159
+ /**
1160
+ * @param element The HTMLElement to check
1161
+ * @returns true if text is truncated, false otherwise
1162
+ */
1163
+ isMultiLineTruncated(element) {
1164
+ if (!element)
1165
+ return false;
1166
+ return element.scrollHeight > element.clientHeight;
1167
+ }
1168
+ 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 }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
1169
+ 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 Kindly ensure that you have enrolled in the Comprehensive Assessment Program and completed all the required courses to unlock the Final Assessment.\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 <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 <!-- 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 flex-col gap-2\">\n <div class=\"flex items-center justify-start gap-4 w-100\">\n <span class=\"milestone-progress-text nodtranslate\">{{getMilestoneCompletedCount()}} of {{content?.leafNodesCount || 0}} completed</span>\n <!-- View Achievement Button - Shown only when all mandatory content AND milestone assessment are completed -->\n <ng-container *ngIf=\"isMilestoneComplete(content?.identifier)\">\n <button type=\"button\" class=\"view-achievement-btn ml-4\" [disabled]=\"achievementLoading\"\n (click)=\"viewMilestoneAchievement($event, content)\">\n <span *ngIf=\"!achievementLoading\">View Achievement</span>\n <mat-spinner *ngIf=\"achievementLoading\" [diameter]=\"16\" [strokeWidth]=\"2\" color=\"primary\" class=\"inline-spinner\"></mat-spinner>\n </button>\n </ng-container>\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\" style=\"white-space: normal; word-wrap: break-word; display: inline-block; max-width: 100%;\">\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: [
1170
+ trigger('panelInOut', [
1171
+ transition('void => *', [
1172
+ style({ transform: 'translateY(-10%)', opacity: '0' }),
1173
+ animate(250)
1174
+ ]),
1175
+ transition('* => void', [
1176
+ animate(200, style({ transform: 'translateY(-10%)', opacity: '0' }))
1177
+ ])
1178
+ ])
1179
+ ] }); }
1180
+ }
1181
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AppTocContentCardV2Component, decorators: [{
1182
+ type: Component,
1183
+ args: [{ selector: 'ws-widget-app-toc-content-card-v2', animations: [
1184
+ trigger('panelInOut', [
1185
+ transition('void => *', [
1186
+ style({ transform: 'translateY(-10%)', opacity: '0' }),
1187
+ animate(250)
1188
+ ]),
1189
+ transition('* => void', [
1190
+ animate(200, style({ transform: 'translateY(-10%)', opacity: '0' }))
1191
+ ])
1192
+ ])
1193
+ ], 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 Kindly ensure that you have enrolled in the Comprehensive Assessment Program and completed all the required courses to unlock the Final Assessment.\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 <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 <!-- 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 flex-col gap-2\">\n <div class=\"flex items-center justify-start gap-4 w-100\">\n <span class=\"milestone-progress-text nodtranslate\">{{getMilestoneCompletedCount()}} of {{content?.leafNodesCount || 0}} completed</span>\n <!-- View Achievement Button - Shown only when all mandatory content AND milestone assessment are completed -->\n <ng-container *ngIf=\"isMilestoneComplete(content?.identifier)\">\n <button type=\"button\" class=\"view-achievement-btn ml-4\" [disabled]=\"achievementLoading\"\n (click)=\"viewMilestoneAchievement($event, content)\">\n <span *ngIf=\"!achievementLoading\">View Achievement</span>\n <mat-spinner *ngIf=\"achievementLoading\" [diameter]=\"16\" [strokeWidth]=\"2\" color=\"primary\" class=\"inline-spinner\"></mat-spinner>\n </button>\n </ng-container>\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\" style=\"white-space: normal; word-wrap: break-word; display: inline-block; max-width: 100%;\">\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"] }]
1194
+ }], 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 }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { content: [{
1195
+ type: Input
1196
+ }], expandAll: [{
1197
+ type: Input
1198
+ }], rootId: [{
1199
+ type: Input
1200
+ }], rootContentType: [{
1201
+ type: Input
1202
+ }], forPreview: [{
1203
+ type: Input
1204
+ }], batchId: [{
1205
+ type: Input
1206
+ }], componentName: [{
1207
+ type: Input
1208
+ }], index: [{
1209
+ type: Input
1210
+ }], pathSet: [{
1211
+ type: Input
1212
+ }], expandActive: [{
1213
+ type: Input
1214
+ }], hierarchyMapData: [{
1215
+ type: Input
1216
+ }], batchData: [{
1217
+ type: Input
1218
+ }], isPreAssessment: [{
1219
+ type: Input
1220
+ }], baseContentReadData: [{
1221
+ type: Input
1222
+ }], mlCourse: [{
1223
+ type: Input
1224
+ }], parentMilestoneLocked: [{
1225
+ type: Input
1226
+ }] } });
1227
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLXRvYy1jb250ZW50LWNhcmQtdjIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicmFyeS9zdW5iaXJkLWNiL3RvYy9zcmMvbGliL19jb2xsZWN0aW9uL19jb21tb24vY29udGVudC10b2MvYXBwLXRvYy1jb250ZW50LWNhcmQtdjIvYXBwLXRvYy1jb250ZW50LWNhcmQtdjIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicmFyeS9zdW5iaXJkLWNiL3RvYy9zcmMvbGliL19jb2xsZWN0aW9uL19jb21tb24vY29udGVudC10b2MvYXBwLXRvYy1jb250ZW50LWNhcmQtdjIvYXBwLXRvYy1jb250ZW50LWNhcmQtdjIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQWtFLE1BQU0sZUFBZSxDQUFBO0FBQ2hILE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQTtBQUN0RSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQTtBQUU5RSxPQUFPLEVBQWdCLFFBQVEsRUFBeUIsTUFBTSxzQkFBc0IsQ0FBQTtBQUNwRixPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSx1REFBdUQsQ0FBQTtBQUVsRyxPQUFPLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUE7QUFDekUsbUJBQW1CO0FBQ25CLE9BQU8sQ0FBQyxNQUFNLFFBQVEsQ0FBQTtBQUN0QixPQUFPLE1BQU0sTUFBTSxRQUFRLENBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUF3QjNCLE1BQU0sT0FBTyw0QkFBNEI7SUE4RHZDLFlBQ1UsTUFBb0IsRUFDcEIsTUFBaUIsRUFDakIsUUFBbUIsRUFDbkIsa0JBQXNDLEVBQ3RDLFNB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RUFBRSxTQUFTLEVBQUUsa0JBQWtCLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7NkJBQ3JFLENBQUM7eUJBQ0gsQ0FBQztxQkFDSDsyWUFHUSxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLG1CQUFtQjtzQkFBM0IsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLHFCQUFxQjtzQkFBN0IsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE9uSW5pdCwgT25EZXN0cm95LCBSZW5kZXJlcjIsIFNpbXBsZUNoYW5nZXMsIENoYW5nZURldGVjdG9yUmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSdcbmltcG9ydCB7IE5zQ29udGVudCB9IGZyb20gJy4uLy4uLy4uLy4uL19zZXJ2aWNlcy93aWRnZXQtY29udGVudC5tb2RlbCdcbmltcG9ydCB7IHZpZXdlclJvdXRlR2VuZXJhdG9yIH0gZnJvbSAnLi4vLi4vLi4vLi4vX3NlcnZpY2VzL3ZpZXdlci1yb3V0ZS11dGlsJ1xuaW1wb3J0IHsgTnNBcHBUb2MgfSBmcm9tICcuLi8uLi8uLi8uLi9tb2RlbHMvYXBwLXRvYy5tb2RlbCdcbmltcG9ydCB7IEV2ZW50U2VydmljZSwgV3NFdmVudHMsIENvbmZpZ3VyYXRpb25zU2VydmljZSB9IGZyb20gJ0BzdW5iaXJkLWNiL3V0aWxzLXYyJ1xuaW1wb3J0IHsgQ2VydGlmaWNhdGVEaWFsb2dDb21wb25lbnQgfSBmcm9tICcuLi8uLi9jZXJ0aWZpY2F0ZS1kaWFsb2cvY2VydGlmaWNhdGUtZGlhbG9nLmNvbXBvbmVudCdcbmltcG9ydCB7IE1hdExlZ2FjeURpYWxvZyBhcyBNYXREaWFsb2cgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9sZWdhY3ktZGlhbG9nJ1xuaW1wb3J0IHsgYW5pbWF0ZSwgc3R5bGUsIHRyYW5zaXRpb24sIHRyaWdnZXIgfSBmcm9tICdAYW5ndWxhci9hbmltYXRpb25zJ1xuLyogdHNsaW50OmRpc2FibGUqL1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJ1xuaW1wb3J0IG1vbWVudCBmcm9tICdtb21lbnQnXG5pbXBvcnQgeyBDZXJ0aWZpY2F0ZVNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi8uLi9zZXJ2aWNlcy9jZXJ0aWZpY2F0ZS5zZXJ2aWNlJ1xuaW1wb3J0IHsgQXBwVG9jU2VydmljZSB9IGZyb20gJy4uLy4uLy4uLy4uL3NlcnZpY2VzL2FwcC10b2Muc2VydmljZSdcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnXG5pbXBvcnQgeyBDb250ZW50TGFuZ3VhZ2VTZXJ2aWNlIH0gZnJvbSAnQHN1bmJpcmQtY2IvY29uc3VtcHRpb24nXG5pbXBvcnQgeyBSZXNvdXJjZURvd25sb2FkSGVscGVyU2VydmljZSB9IGZyb20gJy4uLy4uLy4uLy4uL3NlcnZpY2VzL3Jlc291cmNlLWRvd25sb2FkLWhlbHBlci5zZXJ2aWNlJ1xuaW1wb3J0IHsgTWF0TGVnYWN5U25hY2tCYXIgYXMgTWF0U25hY2tCYXIgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9sZWdhY3ktc25hY2stYmFyJ1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd3cy13aWRnZXQtYXBwLXRvYy1jb250ZW50LWNhcmQtdjInLFxuICB0ZW1wbGF0ZVVybDogJy4vYXBwLXRvYy1jb250ZW50LWNhcmQtdjIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9hcHAtdG9jLWNvbnRlbnQtY2FyZC12Mi5jb21wb25lbnQuc2NzcyddLFxuICBhbmltYXRpb25zOiBbXG4gICAgdHJpZ2dlcigncGFuZWxJbk91dCcsIFtcbiAgICAgIHRyYW5zaXRpb24oJ3ZvaWQgPT4gKicsIFtcbiAgICAgICAgc3R5bGUoeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGVZKC0xMCUpJywgb3BhY2l0eTogJzAnIH0pLFxuICAgICAgICBhbmltYXRlKDI1MClcbiAgICAgIF0pLFxuICAgICAgdHJhbnNpdGlvbignKiA9PiB2b2lkJywgW1xuICAgICAgICBhbmltYXRlKDIwMCwgc3R5bGUoeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGVZKC0xMCUpJywgb3BhY2l0eTogJzAnIH0pKVxuICAgICAgXSlcbiAgICBdKVxuICBdXG59KVxuZXhwb3J0IGNsYXNzIEFwcFRvY0NvbnRlbnRDYXJkVjJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gIEBJbnB1dCgpIGNvbnRlbnQ6IE5zQ29udGVudC5JQ29udGVudCB8IG51bGwgPSBudWxsXG4gIEBJbnB1dCgpIGV4cGFuZEFsbCA9IGZhbHNlXG4gIEBJbnB1dCgpIHJvb3RJZCE6IHN0cmluZ1xuICBASW5wdXQoKSByb290Q29udGVudFR5cGUhOiBzdHJpbmdcbiAgQElucHV0KCkgZm9yUHJldmlldyA9IGZhbHNlXG4gIEBJbnB1dCgpIGJhdGNoSWQhOiBzdHJpbmdcbiAgQElucHV0KCkgY29tcG9uZW50TmFtZTogc3RyaW5nID0gJ3RvYydcbiAgQElucHV0KCkgaW5kZXghOiBudW1iZXJcbiAgQElucHV0KCkgcGF0aFNldCE6IGFueVxuICBASW5wdXQoKSBleHBhbmRBY3RpdmUgPSB0cnVlXG4gIEBJbnB1dCgpIGhpZXJhcmNoeU1hcERhdGE6IGFueSA9IHt9XG4gIEBJbnB1dCgpIGJhdGNoRGF0YTogLyoqTnNDb250ZW50LklCYXRjaExpc3RSZXNwb25zZSAqLyBhbnkgfCBudWxsID0gbnVsbFxuICBASW5wdXQoKSBpc1ByZUFzc2Vzc21lbnQgPSBmYWxzZVxuICBASW5wdXQoKSBiYXNlQ29udGVudFJlYWREYXRhOiBOc0NvbnRlbnQuSUNvbnRlbnQgfCBudWxsID0gbnVsbFxuICBASW5wdXQoKSBtbENvdXJzZTogTnNDb250ZW50LklDb250ZW50IHwgbnVsbCA9IG51bGxcbiAgQElucHV0KCkgcGFyZW50TWlsZXN0b25lTG9ja2VkID0gZmFsc2UgLy8gUGFzc2VkIGZyb20gcGFyZW50IHdoZW4gaW5zaWRlIGEgbG9ja2VkIG1pbGVzdG9uZVxuICBoYXNDb250ZW50U3RydWN0dXJlID0gZmFsc2VcbiAgZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmcgPSBmYWxzZVxuICBlbnVtQ29udGVudFR5cGVzID0gTnNDb250ZW50LkVEaXNwbGF5Q29udGVudFR5cGVzXG4gIGNvbnRlbnRTdHJ1Y3R1cmU6IE5zQXBwVG9jLklUb2NTdHJ1Y3R1cmUgPSB7XG4gICAgYXNzZXNzbWVudDogMCxcbiAgICBmaW5hbFRlc3Q6IDAsXG4gICAgY291cnNlOiAwLFxuICAgIGhhbmRzT246IDAsXG4gICAgaW50ZXJhY3RpdmVWaWRlbzogMCxcbiAgICBsZWFybmluZ01vZHVsZTogMCxcbiAgICBvdGhlcjogMCxcbiAgICBwZGY6IDAsXG4gICAgc3VydmV5OiAwLFxuICAgIHBvZGNhc3Q6IDAsXG4gICAgcHJhY3RpY2VUZXN0OiAwLFxuICAgIHF1aXo6IDAsXG4gICAgdmlkZW86IDAsXG4gICAgd2ViTW9kdWxlOiAwLFxuICAgIHdlYlBhZ2U6IDAsXG4gICAgeW91dHViZTogMCxcbiAgICBpbnRlcmFjdGl2ZWNvbnRlbnQ6IDAsXG4gICAgb2ZmbGluZVNlc3Npb246IDAsXG4gIH1cbiAgZGVmYXVsdFRodW1ibmFpbCA9ICcnXG4gIHZpZXdDaGlsZHJlbiA9IGZhbHNlXG4gIHByaW1hcnlDYXRlZ29yeSA9IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5XG4gIHBhZ2VTY3JvbGxTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbiB8IG51bGwgPSBudWxsXG4gIGhhc2htYXBVcGRhdGVkU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb24gfCBudWxsID0gbnVsbFxuICBhY2hpZXZlbWVudExvYWRpbmc6IGJvb2xlYW4gPSBmYWxzZVxuICAvLyBDYWNoZWQgY29tcHV0ZWQgcHJvcGVydGllcyBmb3IgcGVyZm9ybWFuY2Ugb3B0aW1pemF0aW9uXG4gIHByaXZhdGUgX2NhY2hlZElzQ29sbGVjdGlvbjogYm9vbGVhbiA9IGZhbHNlXG4gIHByaXZhdGUgX2NhY2hlZElzTW9kdWxlOiBib29sZWFuID0gZmFsc2VcbiAgcHJpdmF0ZSBfY2FjaGVkSXNSZXNvdXJjZTogYm9vbGVhbiA9IGZhbHNlXG4gIHByaXZhdGUgX2NhY2hlZElzTWlsZXN0b25lOiBib29sZWFuID0gZmFsc2VcbiAgLy8gSU1QT1JUQU5UOiBEZWZhdWx0IHRvIFRSVUUgKGxvY2tlZCkgLSBtaWxlc3RvbmVzIHNob3VsZCBiZSBsb2NrZWQgdW50aWwgZXhwbGljaXRseSB1bmxvY2tlZFxuICBwcml2YXRlIF9jYWNoZWRJc01pbGVzdG9uZUxvY2tlZDogYm9vbGVhbiA9IHRydWVcbiAgcHJpdmF0ZSBfY2FjaGVkSXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQ6IGJvb2xlYW4gPSBmYWxzZVxuICBwcml2YXRlIF9jYWNoZWRJc0NvbnRlbnRVbmxvY2tlZDogYm9vbGVhbiA9IHRydWVcbiAgcHJpdmF0ZSBfY2FjaGVkQ2hlY2tGb3JDdXJhdGVkUHJvZ3JhbTogYm9vbGVhbiA9IGZhbHNlXG4gIHByaXZhdGUgX2NhY2hlZElzTWlsZXN0b25lQXNzZXNzbWVudDogYm9vbGVhbiA9IGZhbHNlXG4gIHByaXZhdGUgX2NhY2hlZElzTWlsZXN0b25lQXNzZXNzbWVudExvY2tlZDogYm9vbGVhbiA9IGZhbHNlXG4gIHByaXZhdGUgX2NhY2hlZFJlc291cmNlTGluazogeyB1cmw6IHN0cmluZzsgcXVlcnlQYXJhbXM6IHsgW2tleTogc3RyaW5nXTogYW55IH0gfSA9IHsgdXJsOiAnJywgcXVlcnlQYXJhbXM6IHt9IH1cbiAgcHJpdmF0ZSBfY2FjaGVkTWlsZXN0b25lQ29tcGxldGVkQ291bnQ6IG51bWJlciA9IDBcbiAgcHJpdmF0ZSBfY2FjaGVJbml0aWFsaXplZDogYm9vbGVhbiA9IGZhbHNlXG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBldmVudHM6IEV2ZW50U2VydmljZSxcbiAgICBwcml2YXRlIGRpYWxvZzogTWF0RGlhbG9nLFxuICAgIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICBwcml2YXRlIGNlcnRpZmljYXRlU2VydmljZTogQ2VydGlmaWNhdGVTZXJ2aWNlLFxuICAgIHByaXZhdGUgYXBwVG9jU3ZjOiBBcHBUb2NTZXJ2aWNlLFxuICAgIHByaXZhdGUgY29udGVudExhbmdTdmM6IENvbnRlbnRMYW5ndWFnZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSByZXNvdXJjZURvd25sb2FkSGVscGVyU3ZjOiBSZXNvdXJjZURvd25sb2FkSGVscGVyU2VydmljZSwgICAgXG4gICAgcHJpdmF0ZSBjb25maWdTdmM6IENvbmZpZ3VyYXRpb25zU2VydmljZSxcbiAgICBwcml2YXRlIHNuYWNrQmFyOiBNYXRTbmFja0JhcixcbiAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWZcbiAgKSB7IH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmV2YWx1YXRlSW1tZWRpYXRlQ2hpbGRyZW5TdHJ1Y3R1cmUoKVxuICAgIHRoaXMuaW5pdGlhbGl6ZUNvbXB1dGVkUHJvcGVydGllcygpXG4gICAgLy8gdGhpcy5yb3V0ZS5kYXRhLnN1YnNjcmliZShkYXRhID0+IHtcbiAgICAvLyAgICAgdGhpcy5kZWZhdWx0VGh1bWJuYWlsID0gZGF0YS5jb25maWdEYXRhLmRhdGEubG9nb3MuZGVmYXVsdENvbnRlbnRcbiAgICAvLyAgIH1cbiAgICAvLyApXG4gICAgdGhpcy5yZXNvdXJjZVNjcm9sbCgpXG4gICAgXG4gICAgLy8gU3Vic2NyaWJlIHRvIGhhc2htYXAgdXBkYXRlcyB0byByZWNvbXB1dGUgY2FjaGVkIHByb3BlcnRpZXMgd2hlbiBwcm9ncmVzcyBjaGFuZ2VzXG4gICAgdGhpcy5oYXNobWFwVXBkYXRlZFN1YnNjcmlwdGlvbiA9IHRoaXMuYXBwVG9jU3ZjLmhhc2htYXBVcGRhdGVkJC5zdWJzY3JpYmUoKHVwZGF0ZSkgPT4ge1xuICAgICAgaWYgKHVwZGF0ZSAmJiB1cGRhdGUuaGFzaG1hcCkge1xuICAgICAgICAvLyBJTVBPUlRBTlQ6IFVwZGF0ZSBoaWVyYXJjaHlNYXBEYXRhIHdpdGggdGhlIGxhdGVzdCBoYXNobWFwIGZyb20gdGhlIHNlcnZpY2VcbiAgICAgICAgLy8gVGhpcyBlbnN1cmVzIHRoZSBjb21wb25lbnQgdXNlcyB0aGUgdXBkYXRlZCBkYXRhLCBub3QgdGhlIHN0YWxlIEBJbnB1dCByZWZlcmVuY2VcbiAgICAgICAgdGhpcy5oaWVyYXJjaHlNYXBEYXRhID0gdXBkYXRlLmhhc2htYXBcbiAgICAgICAgY29uc3QgcHJldkxvY2tTdGF0ZSA9IHRoaXMuX2NhY2hlZElzTWlsZXN0b25lTG9ja2VkXG4gICAgICAgIHRoaXMuY29tcHV0ZUFsbENhY2hlZFByb3BlcnRpZXMoKVxuICAgICAgICAvLyBGb3JjZSBBbmd1bGFyIGNoYW5nZSBkZXRlY3Rpb24gdG8gdXBkYXRlIHRoZSB2aWV3XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZSBhbGwgY29tcHV0ZWQgcHJvcGVydGllcyBvbmNlIHRvIGF2b2lkIGV4cGVuc2l2ZSBnZXR0ZXIgY2FsY3VsYXRpb25zXG4gICAqIG9uIGV2ZXJ5IGNoYW5nZSBkZXRlY3Rpb24gY3ljbGVcbiAgICovXG4gIHByaXZhdGUgaW5pdGlhbGl6ZUNvbXB1dGVkUHJvcGVydGllcygpIHtcbiAgICB0aGlzLmNvbXB1dGVBbGxDYWNoZWRQcm9wZXJ0aWVzKClcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wdXRlIGFsbCBjYWNoZWQgcHJvcGVydGllcyBhdCBvbmNlIGZvciBwZXJmb3JtYW5jZSBvcHRpbWl6YXRpb25cbiAgICovXG4gIHByaXZhdGUgY29tcHV0ZUFsbENhY2hlZFByb3BlcnRpZXMoKSB7XG4gICAgaWYgKCF0aGlzLmNvbnRlbnQpIHtcbiAgICAgIHRoaXMuX2NhY2hlSW5pdGlhbGl6ZWQgPSBmYWxzZVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgY29udGVudElkID0gdGhpcy5jb250ZW50LmlkZW50aWZpZXJcbiAgICBjb25zdCBoYXNoRGF0YSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YSAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbY29udGVudElkXVxuXG4gICAgLy8gVXNlIGhhc2htYXAgZGF0YSBpZiBhdmFpbGFibGUgZm9yIHByZS1jb21wdXRlZCB2YWx1ZXNcbiAgICBpZiAoaGFzaERhdGEpIHtcbiAgICAgIHRoaXMuX2NhY2hlZElzQ29sbGVjdGlvbiA9IGhhc2hEYXRhLmlzQ29sbGVjdGlvbiAhPT0gdW5kZWZpbmVkID8gXG4gICAgICAgIGhhc2hEYXRhLmlzQ29sbGVjdGlvbiA6IHRoaXMuY29udGVudC5taW1lVHlwZSA9PT0gTnNDb250ZW50LkVNaW1lVHlwZXMuQ09MTEVDVElPTlxuICAgICAgdGhpcy5fY2FjaGVkSXNNb2R1bGUgPSBoYXNoRGF0YS5pc01vZHVsZSAhPT0gdW5kZWZpbmVkID8gXG4gICAgICAgIGhhc2hEYXRhLmlzTW9kdWxlIDogdGhpcy5jb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuTU9EVUxFXG4gICAgICB0aGlzLl9jYWNoZWRJc1Jlc291cmNlID0gaGFzaERhdGEuaXNSZXNvdXJjZSAhPT0gdW5kZWZpbmVkID8gXG4gICAgICAgIGhhc2hEYXRhLmlzUmVzb3VyY2UgOiB0aGlzLmNvbXB1dGVJc1Jlc291cmNlKClcbiAgICAgIHRoaXMuX2NhY2hlZElzTWlsZXN0b25lID0gaGFzaERhdGEuaXNNaWxlc3RvbmUgIT09IHVuZGVmaW5lZCA/IFxuICAgICAgICBoYXNoRGF0YS5pc01pbGVzdG9uZSA6IHRoaXMuY29tcHV0ZUlzTWlsZXN0b25lKClcbiAgICAgIHRoaXMuX2NhY2hlZElzTWlsZXN0b25lTG9ja2VkID0gaGFzaERhdGEuY29tcHV0ZWRJc0xvY2tlZCAhPT0gdW5kZWZpbmVkID8gXG4gICAgICAgIGhhc2hEYXRhLmNvbXB1dGVkSXNMb2NrZWQgOiB0aGlzLmNvbXB1dGVJc01pbGVzdG9uZUxvY2tlZCgpXG4gICAgICB0aGlzLl9jYWNoZWRJc1BhcmVudE1pbGVzdG9uZUxvY2tlZCA9IGhhc2hEYXRhLmlzUGFyZW50TWlsZXN0b25lTG9ja2VkICE9PSB1bmRlZmluZWQgPyBcbiAgICAgICAgaGFzaERhdGEuaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQgOiB0aGlzLmNvbXB1dGVJc1BhcmVudE1pbGVzdG9uZUxvY2tlZCgpXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEZhbGxiYWNrIHRvIGRpcmVjdCBjb21wdXRhdGlvbiBpZiBoYXNobWFwIG5vdCBhdmFpbGFibGVcbiAgICAgIHRoaXMuX2NhY2hlZElzQ29sbGVjdGlvbiA9IHRoaXMuY29udGVudC5taW1lVHlwZSA9PT0gTnNDb250ZW50LkVNaW1lVHlwZXMuQ09MTEVDVElPTlxuICAgICAgdGhpcy5fY2FjaGVkSXNNb2R1bGUgPSB0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5NT0RVTEVcbiAgICAgIHRoaXMuX2NhY2hlZElzUmVzb3VyY2UgPSB0aGlzLmNvbXB1dGVJc1Jlc291cmNlKClcbiAgICAgIHRoaXMuX2NhY2hlZElzTWlsZXN0b25lID0gdGhpcy5jb21wdXRlSXNNaWxlc3RvbmUoKVxuICAgICAgdGhpcy5fY2FjaGVkSXNNaWxlc3RvbmVMb2NrZWQgPSB0aGlzLmNvbXB1dGVJc01pbGVzdG9uZUxvY2tlZCgpXG4gICAgICB0aGlzLl9jYWNoZWRJc1BhcmVudE1pbGVzdG9uZUxvY2tlZCA9IHRoaXMuY29tcHV0ZUlzUGFyZW50TWlsZXN0b25lTG9ja2VkKClcbiAgICB9XG5cbiAgICB0aGlzLl9jYWNoZWRDaGVja0ZvckN1cmF0ZWRQcm9ncmFtID0gdGhpcy5jb21wdXRlQ2hlY2tGb3JDdXJhdGVkUHJvZ3JhbSgpXG4gICAgdGhpcy5fY2FjaGVkSXNDb250ZW50VW5sb2NrZWQgPSB0aGlzLmNvbXB1dGVJc0NvbnRlbnRVbmxvY2tlZCgpXG4gICAgdGhpcy5fY2FjaGVkSXNNaWxlc3RvbmVBc3Nlc3NtZW50ID0gdGhpcy5jb21wdXRlSXNNaWxlc3RvbmVBc3Nlc3NtZW50KClcbiAgICB0aGlzLl9jYWNoZWRJc01pbGVzdG9uZUFzc2Vzc21lbnRMb2NrZWQgPSB0aGlzLmNvbXB1dGVJc01pbGVzdG9uZUFzc2Vzc21lbnRMb2NrZWQoKVxuICAgIHRoaXMuX2NhY2hlZFJlc291cmNlTGluayA9IHRoaXMuY29tcHV0ZVJlc291cmNlTGluaygpXG4gICAgdGhpcy5fY2FjaGVkTWlsZXN0b25lQ29tcGxldGVkQ291bnQgPSB0aGlzLmNvbXB1dGVNaWxlc3RvbmVDb21wbGV0ZWRDb3VudCgpXG4gICAgdGhpcy5fY2FjaGVJbml0aWFsaXplZCA9IHRydWVcbiAgfVxuXG4gIHByaXZhdGUgY29tcHV0ZUlzUmVzb3VyY2UoKTogYm9vbGVhbiB7XG4gICAgaWYgKCF0aGlzLmNvbnRlbnQpIHJldHVybiBmYWxzZVxuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5SRVNPVVJDRSB8fFxuICAgICAgdGhpcy5jb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuUFJBQ1RJQ0VfUkVTT1VSQ0UgfHxcbiAgICAgIHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgfHxcbiAgICAgIHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LkNPTVBfQVNTRVNTTUVOVFxuICAgIClcbiAgfVxuXG4gIHByaXZhdGUgY29tcHV0ZUlzTWlsZXN0b25lKCk6IGJvb2xlYW4ge1xuICAgIGlmICghdGhpcy5jb250ZW50KSByZXR1cm4gZmFsc2VcbiAgICBjb25zdCBwcmltYXJ5Q2F0ID0gdGhpcy5jb250ZW50LnByaW1hcnlDYXRlZ29yeSBhcyBzdHJpbmdcbiAgICBjb25zdCBjb3Vyc2VDYXQgPSB0aGlzLmNvbnRlbnQuY291cnNlQ2F0ZWdvcnkgYXMgc3RyaW5nXG4gICAgcmV0dXJuIHByaW1hcnlDYXQgPT09ICdNaWxlc3RvbmUnIHx8IGNvdXJzZUNhdCA9PT0gJ01pbGVzdG9uZSdcbiAgfVxuXG4gIHByaXZhdGUgY29tcHV0ZUNoZWNrRm9yQ3VyYXRlZFByb2dyYW0oKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMuY29udGVudCAmJiB0aGlzLmNvbnRlbnQucGFyZW50ICYmIHRoaXMuaGllcmFyY2h5TWFwRGF0YSAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbdGhpcy5jb250ZW50LnBhcmVudF0pIHtcbiAgICAgIGNvbnN0IHBhcmVudERhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbdGhpcy5jb250ZW50LnBhcmVudF1cbiAgICAgIHJldHVybiBwYXJlbnREYXRhICYmIHBhcmVudERhdGEucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5DVVJBVEVEX1BST0dSQU0gJiZcbiAgICAgICAgcGFyZW50RGF0YS5jb21wYXRpYmlsaXR5TGV2ZWwgPj0gNSAmJlxuICAgICAgICBwYXJlbnREYXRhLmNvbnRleHRMb2NraW5nVHlwZSA9PT0gTnNDb250ZW50LkVDb250ZXh0TG9ja2luZ1R5cGUuQ09VUlNFX0FTU0VTU01FTlRfT05MWVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIHByaXZhdGUgY29tcHV0ZUlzQ29udGVudFVubG9ja2VkKCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLl9jYWNoZWRDaGVja0ZvckN1cmF0ZWRQcm9ncmFtKSB7XG4gICAgICBpZiAodGhpcy5jb250ZW50ICYmIHRoaXMuY29udGVudC5wYXJlbnQgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhICYmIHRoaXMuaGllcmFyY2h5TWFwRGF0YVt0aGlzLmNvbnRlbnQucGFyZW50XSkge1xuICAgICAgICBjb25zdCBwYXJlbnREYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3RoaXMuY29udGVudC5wYXJlbnRdXG4gICAgICAgIGxldCBjb21wbGV0ZWRMZWFmTm9kZXM6IGFueVtdID0gW11cbiAgICAgICAgcGFyZW50RGF0YS5sZWFmTm9kZXMuZm9yRWFjaCgoX2VsZTogYW55KSA9PiB7XG4gICAgICAgICAgaWYgKHRoaXMuaGllcmFyY2h5TWFwRGF0YSAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbX2VsZV0pIHtcbiAgICAgICAgICAgIGNvbnN0IGNoaWxkRGF0YSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YVtfZWxlXVxuICAgICAgICAgICAgaWYgKGNoaWxkRGF0YSAmJiBjaGlsZERhdGEuY29tcGxldGlvblN0YXR1cyA9PT0gMikge1xuICAgICAgICAgICAgICBjb21wbGV0ZWRMZWFmTm9kZXMucHVzaChjaGlsZERhdGEpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICByZXR1cm4gY29tcGxldGVkTGVhZk5vZGVzLmxlbmd0aCA+PSBwYXJlbnREYXRhLmxlYWZOb2Rlc0NvdW50IC0gMVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICBwcml2YXRlIGNvbXB1dGVSZXNvdXJjZUxpbmsoKTogeyB1cmw6IHN0cmluZzsgcXVlcnlQYXJhbXM6IHsgW2tleTogc3RyaW5nXTogYW55IH0gfSB7XG4gICAgaWYgKHRoaXMuY29udGVudCkge1xuICAgICAgbGV0IG1pbWVUeXBlOiBhbnkgPSAnJ1xuICAgICAgaWYgKHRoaXMuY29udGVudCAmJiB0aGlzLmNvbnRlbnQuY291cnNlQ2F0ZWdvcnkgPT09ICdQcmUgRW5yb2xtZW50IEFzc2Vzc21lbnQnICYmXG4gICAgICAgIHRoaXMuY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5la3N0ZXAuY29udGVudC1jb2xsZWN0aW9uJ1xuICAgICAgKSB7XG4gICAgICAgIG1pbWVUeXBlID0gJ2FwcGxpY2F0aW9uL3ZuZC5zdW5iaXJkLnF1ZXN0aW9uc2V0J1xuICAgICAgICB0aGlzLmNvbnRlbnQubWltZVR5cGUgPSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5GSU5BTF9BU1NFU1NNRU5UXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtaW1lVHlwZSA9IHRoaXMuY29udGVudC5taW1lVHlwZVxuICAgICAgfVxuICAgICAgY29uc3Qgc2VsZWN0ZWRMYW5ndWFnZSA9IHRoaXMubWxDb3Vyc2UgPyB0aGlzLmNvbnRlbnRMYW5nU3ZjLmdldFNlbGVjdGVkTGFuZ3VhZ2UodGhpcy5tbENvdXJzZSkgOiB1bmRlZmluZWRcbiAgICAgIHJldHVybiB2aWV3ZXJSb3V0ZUdlbmVyYXRvcihcbiAgICAgICAgdGhpcy5jb250ZW50LmlkZW50aWZpZXIsXG4gICAgICAgIG1pbWVUeXBlLFxuICAgICAgICB0aGlzLmJhc2VDb250ZW50UmVhZERhdGE/LmlkZW50aWZpZXIgfHwgdGhpcy5yb290SWQsXG4gICAgICAgIHRoaXMuYmFzZUNvbnRlbnRSZWFkRGF0YT8uY29udGVudFR5cGUgfHwgdGhpcy5yb290Q29udGVudFR5cGUsXG4gICAgICAgIHRoaXMuZm9yUHJldmlldyxcbiAgICAgICAgdGhpcy5jb250ZW50LnByaW1hcnlDYXRlZ29yeSxcbiAgICAgICAgdGhpcy5iYXRjaElkLFxuICAgICAgICB0aGlzLmNvbnRlbnQ/Lm5hbWUgfHwgdGhpcy5iYXNlQ29udGVudFJlYWREYXRhPy5uYW1lLFxuICAgICAgICAoc2VsZWN0ZWRMYW5ndWFnZSA/IHNlbGVjdGVkTGFuZ3VhZ2UubGFuZ0lkIDogbnVsbCksXG4gICAgICAgIChzZWxlY3RlZExhbmd1YWdlID8gc2VsZWN0ZWRMYW5ndWFnZS5pZGVudGlmaWVyIDogbnVsbCksXG4gICAgICApXG4gICAgfVxuICAgIHJldHVybiB7IHVybDogJycsIHF1ZXJ5UGFyYW1zOiB7fSB9XG4gIH1cblxuICBwcml2YXRlIGNvbXB1dGVJc01pbGVzdG9uZUxvY2tlZCgpOiBib29sZWFuIHtcbiAgICAvLyBPbmx5IGFwcGx5IG1pbGVzdG9uZSBsb2NraW5nIGZvciBMZWFybmluZyBQYXRod2F5IGNvbnRlbnRcbiAgICBpZiAoIXRoaXMuYmFzZUNvbnRlbnRSZWFkRGF0YSB8fCB0aGlzLmJhc2VDb250ZW50UmVhZERhdGEuY291cnNlQ2F0ZWdvcnkgIT09ICdMZWFybmluZyBQYXRod2F5Jykge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLmNvbnRlbnQpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIC8vIENoZWNrIGlmIGN1cnJlbnQgY29udGVudCBpcyBhIE1pbGVzdG9uZVxuICAgIGlmICghdGhpcy5fY2FjaGVkSXNNaWxlc3RvbmUgJiYgIXRoaXMuY29tcHV0ZUlzTWlsZXN0b25lKCkpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIC8vIENoZWNrIGlmIGhhc2htYXAgaGFzIHByZS1jb21wdXRlZCBsb2NraW5nIHN0YXR1cyAocHJlZmVycmVkIC0gY29tcHV0ZWQgYnkgc2VydmljZSlcbiAgICBjb25zdCBoYXNoRGF0YSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YSAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbdGhpcy5jb250ZW50LmlkZW50aWZpZXJdXG4gICBcbiAgICBcbiAgICAvLyBDUklUSUNBTDogT25seSB1c2UgY29tcHV0ZWRJc0xvY2tlZCBmcm9tIGhhc2htYXAgLSB0aGlzIGlzIHRoZSBTSU5HTEUgU09VUkNFIE9GIFRSVVRIXG4gICAgLy8gVGhlIHNlcnZpY2UgY29tcHV0ZXMgdGhpcyB2YWx1ZSBiYXNlZCBvbiBwcmUtYXNzZXNzbWVudC9taWxlc3RvbmUgY29tcGxldGlvblxuICAgIGlmIChoYXNoRGF0YSAmJiBoYXNoRGF0YS5jb21wdXRlZElzTG9ja2VkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBoYXNoRGF0YS5jb21wdXRlZElzTG9ja2VkXG4gICAgfVxuXG4gICAgLy8gSU1QT1JUQU5UOiBJZiBubyBjb21wdXRlZElzTG9ja2VkIHZhbHVlIGV4aXN0cywgZGVmYXVsdCB0byBMT0NLRURcbiAgICAvLyBUaGlzIGVuc3VyZXMgbWlsZXN0b25lcyBzdGF5IGxvY2tlZCB1bnRpbCB0aGUgc2VydmljZSBleHBsaWNpdGx5IHVubG9ja3MgdGhlbVxuICAgIC8vIERPIE5PVCB1c2UgdGhpcy5jb250ZW50LmlzTG9ja2VkIGFzIGl0IG1heSBiZSBmYWxzZSBieSBkZWZhdWx0IGZyb20gQVBJXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIHByaXZhdGUgY29tcHV0ZUlzUGFyZW50TWlsZXN0b25lTG9ja2VkKCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLnBhcmVudE1pbGVzdG9uZUxvY2tlZCkge1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuYmFzZUNvbnRlbnRSZWFkRGF0YSB8fCB0aGlzLmJhc2VDb250ZW50UmVhZERhdGEuY291cnNlQ2F0ZWdvcnkgIT09ICdMZWFybmluZyBQYXRod2F5Jykge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLmNvbnRlbnQgfHwgIXRoaXMuaGllcmFyY2h5TWFwRGF0YSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaGFzaG1hcCBmb3IgcHJlLWNvbXB1dGVkIHZhbHVlIChzZXQgYnkgY29tcHV0ZU1pbGVzdG9uZUxvY2tpbmdTdGF0dXMpXG4gICAgY29uc3QgaGFzaERhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbdGhpcy5jb250ZW50LmlkZW50aWZpZXJdXG4gICAgaWYgKGhhc2hEYXRhICYmIGhhc2hEYXRhLmlzUGFyZW50TWlsZXN0b25lTG9ja2VkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBoYXNoRGF0YS5pc1BhcmVudE1pbGVzdG9uZUxvY2tlZFxuICAgIH1cblxuICAgIC8vIFRyYXZlcnNlIHVwIHRoZSBoaWVyYXJjaHkgdG8gZmluZCBpZiBhbnkgYW5jZXN0b3IgaXMgYSBsb2NrZWQgTWlsZXN0b25lXG4gICAgbGV0IGN1cnJlbnRQYXJlbnRJZCA9IHRoaXMuY29udGVudC5wYXJlbnRcbiAgICBjb25zdCBtYXhEZXB0aCA9IDVcbiAgICBsZXQgZGVwdGggPSAwXG5cbiAgICB3aGlsZSAoY3VycmVudFBhcmVudElkICYmIGRlcHRoIDwgbWF4RGVwdGgpIHtcbiAgICAgIGNvbnN0IHBhcmVudERhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbY3VycmVudFBhcmVudElkXVxuICAgICAgaWYgKHBhcmVudERhdGEpIHtcbiAgICAgICAgLy8gQ1JJVElDQUw6IE9ubHkgY2hlY2sgY29tcHV0ZWRJc0xvY2tlZCAoY29tcHV0ZWQgYnkgc2VydmljZSksIE5PVCBpc0xvY2tlZCAoQVBJIGRlZmF1bHQpXG4gICAgICAgIC8vIGlzTG9ja2VkIGZyb20gQVBJIG1heSBiZSBmYWxzZSBldmVuIHdoZW4gbWlsZXN0b25lIHNob3VsZCBiZSBsb2NrZWRcbiAgICAgICAgaWYgKChwYXJlbnREYXRhLmlzTWlsZXN0b25lIHx8IHBhcmVudERhdGEucHJpbWFyeUNhdGVnb3J5ID09PSAnTWlsZXN0b25lJyB8fCBwYXJlbnREYXRhLmNvdXJzZUNhdGVnb3J5ID09PSAnTWlsZXN0b25lJykgJiYgXG4gICAgICAgICAgICBwYXJlbnREYXRhLmNvbXB1dGVkSXNMb2NrZWQgPT09IHRydWUpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9XG4gICAgICAgIGN1cnJlbnRQYXJlbnRJZCA9IHBhcmVudERhdGEucGFyZW50XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBicmVha1xuICAgICAgfVxuICAgICAgZGVwdGgrK1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBjdXJyZW50IGNvbnRlbnQgaXMgYSBNSUxFU1RPTkUgYXNzZXNzbWVudCAoRElSRUNUIGNoaWxkIG9mIGEgTWlsZXN0b25lKVxuICAgKiBJTVBPUlRBTlQ6IFRoaXMgc2hvdWxkIE5PVCByZXR1cm4gdHJ1ZSBmb3IgY291cnNlIGFzc2Vzc21lbnRzIGluc2lkZSBjb3Vyc2VzIHdpdGhpbiBtaWxlc3RvbmVzXG4gICAqIE9ubHkgYXNzZXNzbWVudHMgdGhhdCBhcmUgZGlyZWN0IGNoaWxkcmVuIG9mIG1pbGVzdG9uZXMgc2hvdWxkIGJlIGxvY2tlZCBieSBtaWxlc3RvbmUgbG9naWNcbiAgICovXG4gIHByaXZhdGUgY29tcHV0ZUlzTWlsZXN0b25lQXNzZXNzbWVudCgpOiBib29sZWFuIHtcbiAgICBpZiAoIXRoaXMuYmFzZUNvbnRlbnRSZWFkRGF0YSB8fCB0aGlzLmJhc2VDb250ZW50UmVhZERhdGEuY291cnNlQ2F0ZWdvcnkgIT09ICdMZWFybmluZyBQYXRod2F5Jykge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLmNvbnRlbnQgfHwgIXRoaXMuaGllcmFyY2h5TWFwRGF0YSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBhbiBhc3Nlc3NtZW50IHR5cGVcbiAgICAvLyBOb3RlOiBGSU5BTF9BU1NFU1NNRU5UIG1hcHMgdG8gJ0NvdXJzZSBBc3Nlc3NtZW50JyBpbiB0aGUgZW51bSwgbm90ICdGaW5hbCBBc3Nlc3NtZW50J1xuICAgIGNvbnN0IGlzQXNzZXNzbWVudCA9IFxuICAgICAgdGhpcy5jb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gJ0NvdXJzZSBBc3Nlc3NtZW50JyB8fFxuICAgICAgdGhpcy5jb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gJ1N0YW5kYWxvbmUgQXNzZXNzbWVudCcgfHxcbiAgICAgIHRoaXMuY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5zdW5iaXJkLnF1ZXN0aW9uc2V0JyB8fFxuICAgICAgdGhpcy5jb250ZW50Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vcXVpeidcblxuICAgIGlmICghaXNBc3Nlc3NtZW50KSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICAvLyBJTVBPUlRBTlQ6IE9ubHkgcmV0dXJuIHRydWUgaWYgdGhlIERJUkVDVCBwYXJlbnQgaXMgYSBtaWxlc3RvbmVcbiAgICAvLyBBc3Nlc3NtZW50cyBpbnNpZGUgY291cnNlcyAoZ3JhbmRjaGlsZHJlbiBvZiBtaWxlc3RvbmVzKSBzaG91bGQgTk9UIGJlIGxvY2tlZCBieSBtaWxlc3RvbmUgbG9naWNcbiAgICAvLyBUaGV5IGZvbGxvdyB0aGVpciBvd24gY291cnNlJ3MgbG9ja2luZyBydWxlc1xuICAgIFxuICAgIC8vIEdldCB0aGUgcGFyZW50IGZyb20gaGFzaG1hcCAod2hpY2ggd2UgZml4ZWQgdG8gdHJhY2sgY29ycmVjdCBwYXJlbnQtY2hpbGQgcmVsYXRpb25zaGlwcylcbiAgICAvLyBvciBmYWxsYmFjayB0byBjb250ZW50LnBhcmVudCBpZiBoYXNobWFwIGVudHJ5IGRvZXNuJ3QgZXhpc3RcbiAgICBjb25zdCBjb250ZW50SGFzaERhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbdGhpcy5jb250ZW50LmlkZW50aWZpZXJdXG4gICAgY29uc3QgcGFyZW50SWQgPSBjb250ZW50SGFzaERhdGE/LnBhcmVudCB8fCB0aGlzLmNvbnRlbnQucGFyZW50XG4gICAgXG4gICAgaWYgKHBhcmVudElkICYmIHRoaXMuaGllcmFyY2h5TWFwRGF0YVtwYXJlbnRJZF0pIHtcbiAgICAgIGNvbnN0IHBhcmVudERhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbcGFyZW50SWRdXG4gICAgICBcbiAgICAgIFxuICAgICAgXG4gICAgICAvLyBDaGVjayBpZiBESVJFQ1QgcGFyZW50IGlzIGEgbWlsZXN0b25lIC0gT05MWSB0aGlzIGNhc2VcbiAgICAgIGNvbnN0IGlzUGFyZW50TWlsZXN0b25lID0gcGFyZW50RGF0YS5pc01pbGVzdG9uZSB8fCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50RGF0YS5wcmltYXJ5Q2F0ZWdvcnkgPT09ICdNaWxlc3RvbmUnIHx8IFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnREYXRhLmNvdXJzZUNhdGVnb3J5ID09PSAnTWlsZXN0b25lJ1xuICAgICAgXG4gICAgICBpZiAoaXNQYXJlbnRNaWxlc3RvbmUpIHtcbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gRE8gTk9UIGNoZWNrIGdyYW5kcGFyZW50IC0gY291cnNlIGFzc2Vzc21lbnRzIGluc2lkZSBjb3Vyc2VzIHdpdGhpbiBtaWxlc3RvbmVzXG4gICAgICAvLyBzaG91bGQgTk9UIGJlIHRyZWF0ZWQgYXMgbWlsZXN0b25lIGFzc2Vzc21lbnRzXG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBtaWxlc3RvbmUgYXNzZXNzbWVudCBzaG91bGQgYmUgbG9ja2VkXG4gICAqIEFzc2Vzc21lbnQgaXMgbG9ja2VkIGlmOlxuICAgKiAxLiBJdCdzIGFuIGFzc2Vzc21lbnQgdGhhdCBpcyBhIERJUkVDVCBjaGlsZCBvZiBhIG1pbGVzdG9uZVxuICAgKiAyLiBUaGUgcGFyZW50IG1pbGVzdG9uZSBpcyB1bmxvY2tlZCAob3RoZXJ3aXNlIGhhbmRsZWQgYnkgcGFyZW50IG1pbGVzdG9uZSBsb2NrKVxuICAgKiAzLiBOT1QgYWxsIG1hbmRhdG9yeSBjb3Vyc2VzIGluIHRoZSBzYW1lIG1pbGVzdG9uZSBhcmUgY29tcGxldGVkXG4gICAqL1xuICBwcml2YXRlIGNvbXB1dGVJc01pbGVzdG9uZUFzc2Vzc21lbnRMb2NrZWQoKTogYm9vbGVhbiB7XG4gICAgLy8gQ1JJVElDQUw6IE9ubHkgYXBwbHkgbWlsZXN0b25lIGFzc2Vzc21lbnQgbG9ja2luZyBmb3IgTGVhcm5pbmcgUGF0aHdheSBjb250ZW50XG4gICAgLy8gUmVndWxhciBjb3Vyc2VzIHNob3VsZCBORVZFUiBoYXZlIHRoZWlyIGFzc2Vzc21lbnRzIGxvY2tlZCBieSBtaWxlc3RvbmUgbG9naWNcbiAgICBpZiAoIXRoaXMuYmFzZUNvbnRlbnRSZWFkRGF0YSB8fCB0aGlzLmJhc2VDb250ZW50UmVhZERhdGEuY291cnNlQ2F0ZWdvcnkgIT09ICdMZWFybmluZyBQYXRod2F5Jykge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy8gT25seSBhcHBseSB0byBhc3Nlc3NtZW50cyB0aGF0IGFyZSBESVJFQ1QgY2hpbGRyZW4gb2YgbWlsZXN0b25lc1xuICAgIGNvbnN0IGlzTWlsZXN0b25lQXNzZXNzbWVudCA9IHRoaXMuX2NhY2hlZElzTWlsZXN0b25lQXNzZXNzbWVudCB8fCB0aGlzLmNvbXB1dGVJc01pbGVzdG9uZUFzc2Vzc21lbnQoKVxuICAgIFxuICAgIFxuICAgIFxuICAgIGlmICghaXNNaWxlc3RvbmVBc3Nlc3NtZW50KSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiBoYXNobWFwIGhhcyBwcmUtY29tcHV0ZWQgYXNzZXNzbWVudCBsb2NraW5nIHN0YXR1c1xuICAgIGNvbnN0IGhhc2hEYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhICYmIHRoaXMuaGllcmFyY2h5TWFwRGF0YVt0aGlzLmNvbnRlbnQ/LmlkZW50aWZpZXIgfHwgJyddXG4gICAgaWYgKGhhc2hEYXRhICYmIGhhc2hEYXRhLmlzQXNzZXNzbWVudExvY2tlZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gaGFzaERhdGEuaXNBc3Nlc3NtZW50TG9ja2VkXG4gICAgfVxuXG4gICAgLy8gSWYgYWxyZWFkeSBjb21wbGV0ZWQsIGRvbid0IGxvY2tcbiAgICBpZiAodGhpcy5jb250ZW50ICYmICh0aGlzLmNvbnRlbnQuY29tcGxldGlvblN0YXR1cyA9PT0gMiB8fCBcbiAgICAgICAgKHRoaXMuY29udGVudC5jb21wbGV0aW9uUGVyY2VudGFnZSAmJiB0aGlzLmNvbnRlbnQuY29tcGxldGlvblBlcmNlbnRhZ2UgPj0gMTAwKSkpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIC8vIEZvciBtaWxlc3RvbmUgYXNzZXNzbWVudHMsIHRoZSBwYXJlbnQgSVMgdGhlIG1pbGVzdG9uZSAodmVyaWZpZWQgYnkgY29tcHV0ZUlzTWlsZXN0b25lQXNzZXNzbWVudClcbiAgICAvLyBVc2UgaGFzaG1hcCdzIHBhcmVudCB3aGljaCBoYXMgY29ycmVjdCBwYXJlbnQtY2hpbGQgcmVsYXRpb25zaGlwc1xuICAgIGNvbnN0IGNvbnRlbnRIYXNoRGF0YSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YSAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbdGhpcy5jb250ZW50Py5pZGVudGlmaWVyIHx8ICcnXVxuICAgIGNvbnN0IG1pbGVzdG9uZUlkID0gY29udGVudEhhc2hEYXRhPy5wYXJlbnQgfHwgdGhpcy5jb250ZW50Py5wYXJlbnRcbiAgICBcbiAgICBpZiAoIW1pbGVzdG9uZUlkIHx8ICF0aGlzLmhpZXJhcmNoeU1hcERhdGEpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgICBcbiAgICBjb25zdCBtaWxlc3RvbmUgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbbWlsZXN0b25lSWRdXG4gICAgXG4gICAgaWYgKCFtaWxlc3RvbmUpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgICBcbiAgICAvLyBJZiB0aGUgcGFyZW50IG1pbGVzdG9uZSBpdHNlbGYgaXMgbG9ja2VkLCBkb24ndCBhZGQgYWRkaXRpb25hbCBsb2NraW5nXG4gICAgLy8gKHRoZSBwYXJlbnQgbG9jayB3aWxsIGhhbmRsZSBpdClcbiAgICBpZiAobWlsZXN0b25lLmNvbXB1dGVkSXNMb2NrZWQgfHwgbWlsZXN0b25lLmlzTG9ja2VkKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiBhbGwgbWFuZGF0b3J5IENPVVJTRVMgaW4gdGhlIG1pbGVzdG9uZSBhcmUgY29tcGxldGVkXG4gICAgLy8gTm90ZTogT25seSBjaGVja2luZyBjb3Vyc2VzIHRoYXQgYXJlIGRpcmVjdCBjaGlsZHJlbiBvZiB0aGUgbWlsZXN0b25lXG4gICAgbGV0IG1hbmRhdG9yeUNvdW50ID0gMFxuICAgIGxldCBjb21wbGV0ZWRNYW5kYXRvcnlDb3VudCA9IDBcblxuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHRoaXMuaGllcmFyY2h5TWFwRGF0YSkpIHtcbiAgICAgIGNvbnN0IGl0ZW0gPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFba2V5XVxuXG4gICAgICAvLyBPbmx5IGNoZWNrIGl0ZW1zIHRoYXQgYXJlIGRpcmVjdCBjaGlsZHJlbiBvZiB0aGlzIG1pbGVzdG9uZVxuICAgICAgaWYgKGl0ZW0ucGFyZW50ICE9PSBtaWxlc3RvbmVJZCkgY29udGludWVcblxuICAgICAgLy8gT25seSBjb3VudCBjb3Vyc2VzIChub3QgYXNzZXNzbWVudHMsIG5vdCBvdGhlciB0eXBlcylcbiAgICAgIGlmIChpdGVtLnByaW1hcnlDYXRlZ29yeSAhPT0gJ0NvdXJzZScgJiYgIWl0ZW0uaXNDb2xsZWN0aW9uKSBjb250aW51ZVxuICAgICAgXG4gICAgICAvLyBTa2lwIGlmIHRoaXMgaXMgYW4gYXNzZXNzbWVudFxuICAgICAgY29uc3QgaXNJdGVtQXNzZXNzbWVudCA9XG4gICAgICAgIGl0ZW0ucHJpbWFyeUNhdGVnb3J5ID09PSAnQ291cnNlIEFzc2Vzc21lbnQnIHx8XG4gICAgICAgIGl0ZW0ucHJpbWFyeUNhdGVnb3J5ID09PSAnRmluYWwgQXNzZXNzbWVudCcgfHxcbiAgICAgICAgaXRlbS5wcmltYXJ5Q2F0ZWdvcnkgPT09ICdTdGFuZGFsb25lIEFzc2Vzc21lbnQnIHx8XG4gICAgICAgIGl0ZW0ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi92bmQuc3VuYmlyZC5xdWVzdGlvbnNldCdcbiAgICAgIGlmIChpc0l0ZW1Bc3Nlc3NtZW50KSBjb250aW51ZVxuXG4gICAgICAvLyBCeSBkZWZhdWx0LCBjb3Vyc2VzIGFyZSBtYW5kYXRvcnkgdW5sZXNzIGV4cGxpY2l0bHkgbWFya2VkIGFzIG9wdGlvbmFsXG4gICAgICBpZiAoaXRlbS5pc01hbmRhdG9yeSAhPT0gZmFsc2UpIHtcbiAgICAgICAgbWFuZGF0b3J5Q291bnQrK1xuICAgICAgICBjb25zdCBpc0NvbXBsZXRlZCA9IGl0ZW0uY29tcGxldGlvblN0YXR1cyA9PT0gMiB8fCBpdGVtLnN0YXR1cyA9PT0gMiB8fCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0uY29tcGxldGlvblBlcmNlbnRhZ2UgPj0gMTAwIHx8IGl0ZW0ucHJvZ3Jlc3MgPj0gMTAwXG4gICAgICAgIGlmIChpc0NvbXBsZXRlZCkge1xuICAgICAgICAgIGNvbXBsZXRlZE1hbmRhdG9yeUNvdW50KytcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIElmIHRoZXJlIGFyZSBubyBtYW5kYXRvcnkgY291cnNlcywgYXNzZXNzbWVudCBpcyB1bmxvY2tlZFxuICAgIGlmIChtYW5kYXRvcnlDb3VudCA9PT0gMCkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy8gTG9jayBhc3Nlc3NtZW50IGlmIG5vdCBhbGwgbWFuZGF0b3J5IGNvdXJzZXMgYXJlIGNvbXBsZXRlZFxuICAgIGNvbnN0IGFsbE1hbmRhdG9yeUNvbXBsZXRlID0gY29tcGxldGVkTWFuZGF0b3J5Q291bnQgPj0gbWFuZGF0b3J5Q291bnRcbiAgICByZXR1cm4gIWFsbE1hbmRhdG9yeUNvbXBsZXRlXG4gIH1cblxuICAvLyBGT1IgUklHSFQgU0lERSBSRVNPVVJDRSBTQ1JPTEwgT04gVE9DIFBBR0VcbiAgcmVzb3VyY2VTY3JvbGwoKSB7XG4gICAgdGhpcy5wYWdlU2Nyb2xsU3Vic2NyaXB0aW9uID0gdGhpcy5hcHBUb2NTdmMudXBkYXRlUGFnZVNjcm9sbC5zdWJzY3JpYmUoKHZhbHVlOiBib29sZWFuKSA9PiB7XG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5zY3JvbGxWaWV3KClcbiAgICAgICAgfSwgNzAwKVxuICAgICAgfVxuICAgIH0pXG4gIH1cbiAgLy8gVE8gVVBEQVRFIFJFU09VUkNFIEJFSEFWT1VSIFNVQkpFQ1QgRk9SIFJFU09VUkNFIFNDUk9MTFxuICBjaGFuZ2VSZXNvdXJjZSgpIHtcbiAgICB0aGlzLmFwcFRvY1N2Yy5nZXRQYWdlU2Nyb2xsLm5leHQodHJ1ZSlcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcbiAgICBsZXQgc2hvdWxkUmVjb21wdXRlQ2FjaGUgPSBmYWxzZVxuXG4gICAgZm9yIChjb25zdCBwcm9wZXJ0eSBpbiBjaGFuZ2VzKSB7XG4gICAgICBpZiAocHJvcGVydHkgPT09ICdleHBhbmRBbGwnKSB7XG4gICAgICAgIHRoaXMudmlld0NoaWxkcmVuID0gdGhpcy5leHBhbmRBbGxcbiAgICAgIH1cbiAgICAgIGlmIChwcm9wZXJ0eSA9PT0gJ3BhdGhTZXQnICYmIGNoYW5nZXNbJ3BhdGhTZXQnXSkge1xuICAgICAgICBsZXQgY3VycmVudFZhbHVlID0gY2hhbmdlc1sncGF0aFNldCddLmN1cnJlbnRWYWx1ZVxuICAgICAgICBsZXQgcHJldmlvdXNWYWx1ZSA9IGNoYW5nZXNbJ3BhdGhTZXQnXS5wcmV2aW91c1ZhbHVlXG4gICAgICAgIGlmIChjdXJyZW50VmFsdWUgJiYgcHJldmlvdXNWYWx1ZSkge1xuICAgICAgICAgIGNvbnN0IGVxU2V0ID0gKHhzOiBhbnksIHlzOiBhbnkpID0+XG4gICAgICAgICAgICB4cy5zaXplID09PSB5cy5zaXplICYmXG4gICAgICAgICAgICBbLi4ueHNdLmV2ZXJ5KCh4KSA9PiB5cy5oYXMoeCkpXG4gICAgICAgICAgaWYgKCFlcVNldChwcmV2aW91c1ZhbHVlLCBjdXJyZW50VmFsdWUpKSB7IH1cbiAgICAgICAgfVxuICAgICAgICAvLyBpZihwcmV2aW91c1ZhbHVlID09PSB1bmRlZmluZWQpe1xuICAgICAgICAvLyAgIHNldFRpbWVvdXQoKCk9PntcbiAgICAgICAgLy8gICB9LDcwMClcbiAgICAgICAgLy8gfVxuICAgICAgfVxuICAgICAgLy8gdGhpcy5hcHBUb2NTdmMuZ2V0UGFnZVNjcm9sbC5uZXh0KHRydWUpXG5cbiAgICAgIGlmIChwcm9wZXJ0eSA9PT0gJ2hpZXJhcmNoeU1hcERhdGEnKSB7XG4gICAgICAgIGlmIChfLmlzRW1wdHkoY2hhbmdlc1snaGllcmFyY2h5TWFwRGF0YSddLmN1cnJlbnRWYWx1ZSkpIHtcbiAgICAgICAgICAvLyB0aGlzLmxvYWRpbmdPdmVyYWxsUFJvZ3Jlc3MgPSB0cnVlXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKHRoaXMuY29udGVudCkge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVDaGlsZFBhcmVudE1hcCh0aGlzLmNvbnRlbnQuaWRlbnRpZmllcilcbiAgICAgICAgICB9XG4gICAgICAgICAgc2hvdWxkUmVjb21wdXRlQ2FjaGUgPSB0cnVlXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gUmVjb21wdXRlIGNhY2hlIHdoZW4gY3JpdGljYWwgaW5wdXRzIGNoYW5nZVxuICAgICAgaWYgKHByb3BlcnR5ID09PSAnY29udGVudCcgfHwgcHJvcGVydHkgPT09ICdiYXNlQ29udGVudFJlYWREYXRhJyB8fCBcbiAgICAgICAgICBwcm9wZXJ0eSA9PT0gJ2JhdGNoSWQnIHx8IHByb3BlcnR5ID09PSAnZm9yUHJldmlldycgfHwgXG4gICAgICAgICAgcHJvcGVydHkgPT09ICdwYXJlbnRNaWxlc3RvbmVMb2NrZWQnIHx8IHByb3BlcnR5ID09PSAnbWxDb3Vyc2UnKSB7XG4gICAgICAgIHNob3VsZFJlY29tcHV0ZUNhY2hlID0gdHJ1ZVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFJlY29tcHV0ZSBhbGwgY2FjaGVkIHByb3BlcnRpZXMgaWYgbmVlZGVkXG4gICAgaWYgKHNob3VsZFJlY29tcHV0ZUNhY2hlKSB7XG4gICAgICB0aGlzLmNvbXB1dGVBbGxDYWNoZWRQcm9wZXJ0aWVzKClcbiAgICB9XG4gIH1cblxuICBjaGVjayhjb250ZW50OiBhbnkpIHtcbiAgICBpZiAodGhpcy5leHBhbmRBY3RpdmUpIHtcbiAgICAgIGNvbnRlbnQudmlld0NoaWxkcmVuID0gdGhpcy5wYXRoU2V0ICYmIHRoaXMucGF0aFNldC5oYXMoY29udGVudC5pZGVudGlmaWVyKSB8fCBjb250ZW50LnZpZXdDaGlsZHJlblxuICAgIH1cbiAgICByZXR1cm4gY29udGVudC52aWV3Q2hpbGRyZW5cbiAgfVxuXG4gIGdldCBpc0NvbGxlY3Rpb24oKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMuX2NhY2hlSW5pdGlhbGl6ZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLl9jYWNoZWRJc0NvbGxlY3Rpb25cbiAgICB9XG4gICAgaWYgKHRoaXMuY29udGVudCkge1xuICAgICAgcmV0dXJuIHRoaXMuY29udGVudC5taW1lVHlwZSA9PT0gTnNDb250ZW50LkVNaW1lVHlwZXMuQ09MTEVDVElPTlxuICAgIH1cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIGdldCBpc01vZHVsZSgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5fY2FjaGVJbml0aWFsaXplZCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZElzTW9kdWxlXG4gICAgfVxuICAgIGlmICh0aGlzLmNvbnRlbnQpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5NT0RVTEVcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBwdWJsaWMgY2hlY2tNb2R1bGUoY29udGVudDogTnNDb250ZW50LklDb250ZW50IHwgbnVsbCk6IGJvb2xlYW4ge1xuICAgIGlmIChjb250ZW50KSB7XG4gICAgICByZXR1cm4gY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk1PRFVMRVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIGNoZWNrSXNNb2R1bGUoY29udGVudDogYW55KTogYm9vbGVhbiB7XG4gICAgaWYgKGNvbnRlbnQpIHtcbiAgICAgIHJldHVybiBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuTU9EVUxFXG4gICAgfVxuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgZ2V0IGlzQmF0Y2hJblByb2dlc3MoKSB7XG4gICAgaWYgKHRoaXMuYmF0Y2hEYXRhICYmICh0aGlzLmJhdGNoRGF0YS5jb250ZW50ICYmIHRoaXMuYmF0Y2hEYXRhLmNvbnRlbnQubGVuZ3RoKSAmJiB0aGlzLmJhdGNoRGF0YS5lbnJvbGxlZCkge1xuICAgICAgY29uc3QgYmF0Y2hEYXRhID0gdGhpcy5iYXRjaERhdGEuY29udGVudFswXVxuICAgICAgaWYgKGJhdGNoRGF0YSAmJiBiYXRjaERhdGEuZW5kRGF0ZSkge1xuICAgICAgICBjb25zdCBub3cgPSBtb21lbnQoKS5mb3JtYXQoJ1lZWVktTU0tREQnKVxuICAgICAgICBjb25zdCBzdGFydERhdGUgPSBtb21lbnQoYmF0Y2hEYXRhLnN0YXJ0RGF0ZSkuZm9ybWF0KCdZWVlZLU1NLUREJylcbiAgICAgICAgY29uc3QgZW5kRGF0ZSA9IGJhdGNoRGF0YS5lbmREYXRlID8gbW9tZW50KGJhdGNoRGF0YS5lbmREYXRlKS5mb3JtYXQoJ1lZWVktTU0tREQnKSA6IG5vd1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIC8vIGJhdGNoLnN0YXR1cyAmJlxuICAgICAgICAgIG1vbWVudChzdGFydERhdGUpLmlzU2FtZU9yQmVmb3JlKG5vdylcbiAgICAgICAgICAmJiBtb21lbnQoZW5kRGF0ZSkuaXNTYW1lT3JBZnRlcihub3cpXG4gICAgICAgIClcbiAgICAgIH0gcmV0dXJuIHRydWVcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBnZXQgaXNSZXNvdXJjZSgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5fY2FjaGVJbml0aWFsaXplZCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZElzUmVzb3VyY2VcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY29tcHV0ZUlzUmVzb3VyY2UoKVxuICB9XG5cbiAgZ2V0IHJlc291cmNlTGluaygpOiB7IHVybDogc3RyaW5nOyBxdWVyeVBhcmFtczogeyBba2V5OiBzdHJpbmddOiBhbnkgfSB9IHtcbiAgICBpZiAodGhpcy5fY2FjaGVJbml0aWFsaXplZCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZFJlc291cmNlTGlua1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jb21wdXRlUmVzb3VyY2VMaW5rKClcbiAgfVxuXG4gIHB1YmxpYyBwcm9ncmVzc0NvbG9yKCk6IHN0cmluZyB7XG4gICAgLy8gaWYgKHRoaXMuY3VycmVudFByb2dyZXNzIDw9IDMwKSB7XG4gICAgLy8gICByZXR1cm4gJyNEMTM5MjQnXG4gICAgLy8gfSBpZiAodGhpcy5jdXJyZW50UHJvZ3Jlc3MgPiAzMCAmJiB0aGlzLmN1cnJlbnRQcm9ncmVzcyA8PSA3MCkge1xuICAgIC8vICAgcmV0dXJuICcjRTk5RTM4J1xuICAgIC8vIH1cbiAgICAvLyBpZiAodGhpcy5jdXJyZW50UHJvZ3Jlc3MgPiA3MCAmJiB0aGlzLmN1cnJlbnRQcm9ncmVzcyA8PSAxMDApIHtcbiAgICAvLyAgIHJldHVybiAnIzFEODkyMydcbiAgICAvLyB9XG5cbiAgICByZXR1cm4gJyMxRDg5MjMnXG4gIH1cbiAgcHVibGljIHByb2dyZXNzQ29sb3IyKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuICcjZjI3ZDAwJ1xuICB9XG5cbiAgcHJpdmF0ZSBldmFsdWF0ZUltbWVkaWF0ZUNoaWxkcmVuU3RydWN0dXJlKCkge1xuICAgIGlmICh0aGlzLmNvbnRlbnQgJiYgdGhpcy5jb250ZW50LmNoaWxkcmVuICYmIHRoaXMuY29udGVudC5jaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgIHRoaXMuY29udGVudC5jaGlsZHJlbi5mb3JFYWNoKChjaGlsZDogTnNDb250ZW50LklDb250ZW50KSA9PiB7XG4gICAgICAgIGlmIChjaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LkNPVVJTRSkge1xuICAgICAgICAgIHRoaXMuY29udGVudFN0cnVjdHVyZS5jb3Vyc2UgKz0gMVxuICAgICAgICB9IGVsc2UgaWYgKGNoaWxkLnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuS05PV0xFREdFX0FSVElGQUNUKSB7XG4gICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLm90aGVyICs9IDFcbiAgICAgICAgfSBlbHNlIGlmIChjaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5Lk1PRFVMRSkge1xuICAgICAgICAgIHRoaXMuY29udGVudFN0cnVjdHVyZS5sZWFybmluZ01vZHVsZSArPSAxXG4gICAgICAgIH0gZWxzZSBpZiAoY2hpbGQucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5PRkZMSU5FX1NFU1NJT04pIHtcbiAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUub2ZmbGluZVNlc3Npb24gKz0gMVxuICAgICAgICB9IGVsc2UgaWYgKGNoaWxkLnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuUkVTT1VSQ0UpIHtcbiAgICAgICAgICBzd2l0Y2ggKGNoaWxkLm1pbWVUeXBlKSB7XG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLkhBTkRTX09OOlxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUuaGFuZHNPbiArPSAxXG4gICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLk1QMzpcbiAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLnBvZGNhc3QgKz0gMVxuICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5NUDQ6XG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLk0zVTg6XG4gICAgICAgICAgICAgIHRoaXMuY29udGVudFN0cnVjdHVyZS52aWRlbyArPSAxXG4gICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLklOVEVSQUNUSU9OOlxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUuaW50ZXJhY3RpdmVWaWRlbyArPSAxXG4gICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLlBERjpcbiAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLnBkZiArPSAxXG4gICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLk9GRkxJTkVfU0VTU0lPTjpcbiAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLm9mZmxpbmVTZXNzaW9uICs9IDFcbiAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuU1VSVkVZOlxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUuc3VydmV5ICs9IDFcbiAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuSFRNTDpcbiAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLndlYlBhZ2UgKz0gMVxuICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5RVUlaOlxuICAgICAgICAgICAgICBpZiAoY2hpbGQucmVzb3VyY2VUeXBlID09PSAnQXNzZXNzbWVudCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUuYXNzZXNzbWVudCArPSAxXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLnF1aXogKz0gMVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLlBSQUNUSUNFX1JFU09VUkNFOlxuICAgICAgICAgICAgICAvLyBjYXNlIE5zQ29udGVudC5FTWltZVR5cGVzLkZJTkFMX0FTU0VTU01FTlQ6XG4gICAgICAgICAgICAgIC8vIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuUFJBQ1RJQ0VfUkVTT1VSQ0U6XG4gICAgICAgICAgICAgIHRoaXMuY29udGVudFN0cnVjdHVyZS5wcmFjdGljZVRlc3QgKz0gMVxuICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgY2FzZSBOc0NvbnRlbnQuRU1pbWVUeXBlcy5XRUJfTU9EVUxFOlxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRTdHJ1Y3R1cmUud2ViTW9kdWxlICs9IDFcbiAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGNhc2UgTnNDb250ZW50LkVNaW1lVHlwZXMuWU9VVFVCRTpcbiAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLnlvdXR1YmUgKz0gMVxuICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgdGhpcy5jb250ZW50U3RydWN0dXJlLm90aGVyICs9IDFcbiAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICAgIGZvciAoY29uc3Qga2V5IGluIHRoaXMuY29udGVudFN0cnVjdHVyZSkge1xuICAgICAgaWYgKHRoaXMuY29udGVudFN0cnVjdHVyZVtrZXldID4gMCkge1xuICAgICAgICB0aGlzLmhhc0NvbnRlbnRTdHJ1Y3R1cmUgPSB0cnVlXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2V0IGNvbnRleHRQYXRoKCkge1xuICAgIHJldHVybiB7XG4gICAgICBjb250ZXh0SWQ6IHRoaXMucm9vdElkLFxuICAgICAgY29udGV4dFBhdGg6IHRoaXMucm9vdENvbnRlbnRUeXBlLFxuICAgICAgYmF0Y2hJZDogdGhpcy5iYXRjaElkLFxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBjb250ZW50VHJhY2tCeShfaW5kZXg6IG51bWJlciwgY29udGVudDogTnNDb250ZW50LklDb250ZW50KSB7XG4gICAgaWYgKCFjb250ZW50KSB7XG4gICAgICByZXR1cm4gbnVsbFxuICAgIH1cbiAgICByZXR1cm4gY29udGVudC5pZGVudGlmaWVyXG4gIH1cblxuICBwdWJsaWMgcmFpc2VUZWxlbWV0cnkoKSB7XG4gICAgLy8gaWYgKHRoaXMuZm9yUHJldmlldykgeyByZXR1cm4gfVxuICAgIGlmICh0aGlzLmNvbnRlbnQpIHtcbiAgICAgIHRoaXMuZXZlbnRzLnJhaXNlSW50ZXJhY3RUZWxlbWV0cnkoXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiAnY2xpY2snLFxuICAgICAgICAgIHN1YlR5cGU6IGBjYXJkLXRvY0NvbnRlbnRDYXJkYCxcbiAgICAgICAgICAvLyBpZDogdGhpcy5jb250ZW50LmlkZW50aWZpZXIgfHwgJycsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAvLyBjb250ZW50SWQ6IHRoaXMuY29udGVudC5pZGVudGlmaWVyIHx8ICcnLFxuICAgICAgICAgIC8vIGNvbnRlbnRUeXBlOiB0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5LFxuICAgICAgICAgIGlkOiB0aGlzLmNvbnRlbnQuaWRlbnRpZmllciB8fCAnJyxcbiAgICAgICAgICB0eXBlOiB0aGlzLmNvbnRlbnQucHJpbWFyeUNhdGVnb3J5LFxuICAgICAgICAgIHJvbGx1cDoge1xuICAgICAgICAgICAgbDE6IHRoaXMucm9vdElkIHx8ICcnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdmVyOiBgJHt0aGlzLmNvbnRlbnQudmVyc2lvbn0keycnfWAsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBwYWdlSWRFeHQ6IGAke18uY2FtZWxDYXNlKHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkpfS1jYXJkYCxcbiAgICAgICAgICBtb2R1bGU6IF8uY2FtZWxDYXNlKHRoaXMuY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkpLFxuICAgICAgICB9KVxuICAgIH1cbiAgfVxuICBnZXQgaXNBbGxvd2VkKCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLmNvbnRlbnQpIHtcbiAgICAgIHJldHVybiAhKE5zQ29udGVudC5VTl9TVVBQT1JURURfREFUQV9UWVBFU19GT1JfTk9OX0JBVENIX1VTRVJTLmluZGV4T2YodGhpcy5jb250ZW50Lm1pbWVUeXBlKSA+PSAwKVxuICAgIH0gcmV0dXJuIGZhbHNlXG4gIH1cblxuICBnZXQgaXNFbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICBnZXQgaXNFbnJvbGxlZCgpOiBib29sZWFuIHtcbiAgICAvLyBDaGVjayBib3RoIGJhdGNoSWQgYW5kIGJhdGNoRGF0YS5lbnJvbGxlZCB0byBzdXBwb3J0IExlYXJuaW5nIFBhdGh3YXlzXG4gICAgLy8gd2hlcmUgYmF0Y2hJZCBtaWdodCBub3QgYmUgZGlyZWN0bHkgc2V0IGJ1dCB1c2VyIGlzIGVucm9sbGVkIGluIGNvdXJzZXMgd2l0aGluIHRoZSBwYXRod2F5XG4gICAgcmV0dXJuIHRoaXMuYmF0Y2hJZCA/IHRydWUgOiAodGhpcy5iYXRjaERhdGE/LmVucm9sbGVkIHx8IGZhbHNlKVxuICB9XG5cbiAgdXBkYXRlQ2hpbGRQYXJlbnRNYXAoaWRlbnRpZmllcjogc3RyaW5nKSB7XG4gICAgaWYgKHRoaXMuaGllcmFyY2h5TWFwRGF0YSAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl0pIHtcbiAgICAgIGxldCBsb2NhbENvbnRlbnREYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2lkZW50aWZpZXJdXG4gICAgICBpZiAoXG4gICAgICAgICEobG9jYWxDb250ZW50RGF0YS5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LlJFU09VUkNFXG4gICAgICAgICAgfHwgbG9jYWxDb250ZW50RGF0YS5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFXG4gICAgICAgICAgfHwgbG9jYWxDb250ZW50RGF0YS5wcmltYXJ5Q2F0ZWdvcnkgPT09IE5zQ29udGVudC5FUHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlRcbiAgICAgICAgICB8fCBsb2NhbENvbnRlbnREYXRhLnByaW1hcnlDYXRlZ29yeSA9PT0gTnNDb250ZW50LkVQcmltYXJ5Q2F0ZWdvcnkuQ09NUF9BU1NFU1NNRU5UKVxuICAgICAgKSB7XG4gICAgICAgIC8vIHJlYWwgcGVyY2VudCBsb2dpY1xuICAgICAgICAvLyBjb25zdCB0b3RhbCA9IGxvY2FsQ29udGVudERhdGEubGVhZk5vZGVzLnJlZHVjZSgoc3VtOiBudW1iZXIsIGNoaWxkSWQ6IHN0cmluZykgPT4ge1xuICAgICAgICAvLyAgIHJldHVybiBzdW0gKyBOdW1iZXIodGhpcy5oaWVyYXJjaHlNYXBEYXRhW2NoaWxkSWRdLmNvbXBsZXRpb25QZXJjZW50YWdlIHx8IDApXG4gICAgICAgIC8vIH0sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKVxuICAgICAgICAvLyBpZih0b3RhbCA+IDApIHtcbiAgICAgICAgLy8gICB0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl1bJ2NvbXBsZXRpb25QZXJjZW50YWdlJ10gPSB0b3RhbCAvIF8udG9JbnRlZ2VyKF8uZ2V0KHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXSwgJ2xlYWZOb2Rlc0NvdW50JykpXG4gICAgICAgIC8vIH1cbiAgICAgICAgaWYgKGxvY2FsQ29udGVudERhdGEucHJpbWFyeUNhdGVnb3J5ID09PSBOc0NvbnRlbnQuRVByaW1hcnlDYXRlZ29yeS5NT0RVTEUpIHtcbiAgICAgICAgICB0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl1bJ2R1cmF0aW9uJ10gPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl0ubGVhZk5vZGVzLnJlZHVjZShcbiAgICAgICAgICAgIChzdW06IGFueSwgY2hpbGRJRDogYW55KSA9PiB7XG4gICAgICAgICAgICAgIGlmICh0aGlzLmhpZXJhcmNoeU1hcERhdGEgJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2NoaWxkSURdKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHN1bSArIE51bWJlcih0aGlzLmhpZXJhcmNoeU1hcERhdGFbY2hpbGRJRF0uZHVyYXRpb24gfHwgdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2NoaWxkSURdLmV4cGVjdGVkRHVyYXRpb24gfHwgMClcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB9LCAwKVxuICAgICAgICB9XG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlXG4gICAgICAgIGNvbnN0IGNvbXBsZXRlZEl0ZW1zID0gXy5maWx0ZXIodGhpcy5oaWVyYXJjaHlNYXBEYXRhW2lkZW50aWZpZXJdLmxlYWZOb2RlcywgciA9PiAodGhpcy5oaWVyYXJjaHlNYXBEYXRhW3JdICYmICh0aGlzLmhpZXJhcmNoeU1hcERhdGFbcl0uY29tcGxldGlvblN0YXR1cyA9PT0gMiB8fCB0aGlzLmhpZXJhcmNoeU1hcERhdGFbcl0uY29tcGxldGlvblBlcmNlbnRhZ2UgPT09IDEwMCkpKVxuICAgICAgICBjb25zdCB0b3RhbENvdW50ID0gXy50b0ludGVnZXIoXy5nZXQodGhpcy5oaWVyYXJjaHlNYXBEYXRhW2lkZW50aWZpZXJdLCAnbGVhZk5vZGVzQ291bnQnKSkgfHwgMVxuICAgICAgICB0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl1bJ2NvbXBsZXRpb25QZXJjZW50YWdlJ10gPSBOdW1iZXIoKChjb21wbGV0ZWRJdGVtcy5sZW5ndGggLyB0b3RhbENvdW50KSAqIDEwMCkudG9GaXhlZCgpKVxuICAgICAgICB0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl1bJ2NvbXBsZXRpb25TdGF0dXMnXSA9ICh0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl0uY29tcGxldGlvblBlcmNlbnRhZ2UgPj0gMTAwKSA/IDIgOiAxXG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2lkZW50aWZpZXJdXG4gICAgfVxuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgZ2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoaWRlbnRpZmllcjogc3RyaW5nKSB7XG4gICAgLy8gY29uc3QgaXRlbSA9IHRoaXMudXBkYXRlQ2hpbGRQYXJlbnRNYXAoaWRlbnRpZmllcilcbiAgICBsZXQgcGVyY2VudCA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YSAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl0gJiYgdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2lkZW50aWZpZXJdLmNvbXBsZXRpb25QZXJjZW50YWdlIHx8IDBcbiAgICByZXR1cm4gdGhpcy5yb3VuZElmRGVjaW1hbChwZXJjZW50KVxuICB9XG5cbiAgcm91bmRJZkRlY2ltYWwodmFsdWU6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHBhcnNlRmxvYXQodmFsdWUudG9GaXhlZCgyKSlcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlXG4gIH1cblxuXG4gIGdldENvbXBsZXRpb25TdGF0dXMoaWRlbnRpZmllcjogc3RyaW5nKSB7XG4gICAgLy8gY29uc3QgaXRlbSA9IHRoaXMudXBkYXRlQ2hpbGRQYXJlbnRNYXAoaWRlbnRpZmllcilcbiAgICByZXR1cm4gdGhpcy5oaWVyYXJjaHlNYXBEYXRhICYmIHRoaXMuaGllcmFyY2h5TWFwRGF0YVtpZGVudGlmaWVyXSAmJiB0aGlzLmhpZXJhcmNoeU1hcERhdGFbaWRlbnRpZmllcl0uY29tcGxldGlvblN0YXR1c1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIG1pbGVzdG9uZSBpcyBjb21wbGV0ZSBiYXNlZCBvbiBtYW5kYXRvcnkgY29udGVudCBhbmQgYXNzZXNzbWVudCBjb21wbGV0aW9uXG4gICAqIFJldHVybnMgdHJ1ZSBvbmx5IHdoZW46XG4gICAqIDEuIEFsbCBtYW5kYXRvcnkgY29udGVudCBpcyBjb21wbGV0ZWQgKG9yIG5vIG1hbmRhdG9yeSBjb250ZW50IGV4aXN0cylcbiAgICogMi4gTWlsZXN0b25lIGFzc2Vzc21lbnQgaXMgY29tcGxldGVkIChvciBubyBhc3Nlc3NtZW50IGV4aXN0cylcbiAgICovXG4gIGlzTWlsZXN0b25lQ29tcGxldGUoaWRlbnRpZmllcjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgaWYgKCF0aGlzLmhpZXJhcmNoeU1hcERhdGEpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgICBjb25zdCBtaWxlc3RvbmVEYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2lkZW50aWZpZXJdXG4gICAgaWYgKCFtaWxlc3RvbmVEYXRhKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiBhbGwgbWFuZGF0b3J5IGNvbnRlbnQgQU5EIG1pbGVzdG9uZSBhc3Nlc3NtZW50IGFyZSBjb21wbGV0ZWRcbiAgICBsZXQgaGFzTWFuZGF0b3J5Q29udGVudCA9IGZhbHNlXG4gICAgbGV0IGFsbE1hbmRhdG9yeUNvbXBsZXRlID0gdHJ1ZVxuICAgIGxldCBoYXNNaWxlc3RvbmVBc3Nlc3NtZW50ID0gZmFsc2VcbiAgICBsZXQgbWlsZXN0b25lQXNzZXNzbWVudENvbXBsZXRlID0gZmFsc2VcblxuICAgIC8vIENoZWNrIGFsbCBkaXJlY3QgY2hpbGRyZW4gb2YgdGhlIG1pbGVzdG9uZVxuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHRoaXMuaGllcmFyY2h5TWFwRGF0YSkpIHtcbiAgICAgIGNvbnN0IGl0ZW0gPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFba2V5XVxuXG4gICAgICAvLyBPbmx5IGNoZWNrIGRpcmVjdCBjaGlsZHJlblxuICAgICAgaWYgKGl0ZW0ucGFyZW50ICE9PSBpZGVudGlmaWVyKSBjb250aW51ZVxuXG4gICAgICAvLyBDaGVjayBpZiB0aGlzIGlzIHRoZSBtaWxlc3RvbmUgYXNzZXNzbWVudFxuICAgICAgY29uc3QgaXNBc3Nlc3NtZW50ID0gXG4gICAgICAgIGl0ZW0ucHJpbWFyeUNhdGVnb3J5ID09PSAnQ291cnNlIEFzc2Vzc21lbnQnIHx8XG4gICAgICAgIGl0ZW0ucHJpbWFyeUNhdGVnb3J5ID09PSAnRmluYWwgQXNzZXNzbWVudCcgfHxcbiAgICAgICAgaXRlbS5wcmltYXJ5Q2F0ZWdvcnkgPT09ICdTdGFuZGFsb25lIEFzc2Vzc21lbnQnXG5cbiAgICAgIGlmIChpc0Fzc2Vzc21lbnQpIHtcbiAgICAgICAgaGFzTWlsZXN0b25lQXNzZXNzbWVudCA9IHRydWVcbiAgICAgICAgY29uc3QgaXNDb21wbGV0ZWQgPSBpdGVtLmNvbXBsZXRpb25TdGF0dXMgPT09IDIgfHwgaXRlbS5zdGF0dXMgPT09IDIgfHwgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtLmNvbXBsZXRpb25QZXJjZW50YWdlID49IDEwMCB8fCBpdGVtLnByb2dyZXNzID49IDEwMFxuICAgICAgICBpZiAoaXNDb21wbGV0ZWQpIHtcbiAgICAgICAgICBtaWxlc3RvbmVBc3Nlc3NtZW50Q29tcGxldGUgPSB0cnVlXG4gICAgICAgIH1cbiAgICAgICAgY29udGludWUgLy8gU2tpcCB0byBuZXh0IGl0ZW1cbiAgICAgIH1cblxuICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBtYW5kYXRvcnkgY29udGVudCAoY291cnNlcy9jb2xsZWN0aW9ucylcbiAgICAgIGlmIChpdGVtLnByaW1hcnlDYXRlZ29yeSA9PT0gJ0NvdXJzZScgfHwgaXRlbS5pc0NvbGxlY3Rpb24pIHtcbiAgICAgICAgY29uc3QgaXNNYW5kYXRvcnkgPSBpdGVtLmlzTWFuZGF0b3J5ICE9PSBmYWxzZSAvLyBEZWZhdWx0IGlzIG1hbmRhdG9yeVxuICAgICAgICBcbiAgICAgICAgaWYgKGlzTWFuZGF0b3J5KSB7XG4gICAgICAgICAgaGFzTWFuZGF0b3J5Q29udGVudCA9IHRydWVcbiAgICAgICAgICBjb25zdCBpc0NvbXBsZXRlZCA9IGl0ZW0uY29tcGxldGlvblN0YXR1cyA9PT0gMiB8fCBpdGVtLnN0YXR1cyA9PT0gMiB8fCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS5jb21wbGV0aW9uUGVyY2VudGFnZSA+PSAxMDAgfHwgaXRlbS5wcm9ncmVzcyA+PSAxMDBcbiAgICAgICAgICBpZiAoIWlzQ29tcGxldGVkKSB7XG4gICAgICAgICAgICBhbGxNYW5kYXRvcnlDb21wbGV0ZSA9IGZhbHNlXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gTWlsZXN0b25lIGlzIGNvbXBsZXRlIHdoZW46XG4gICAgLy8gMS4gQWxsIG1hbmRhdG9yeSBjb250ZW50IGlzIGNvbXBsZXRlZCAob3Igbm8gbWFuZGF0b3J5IGNvbnRlbnQgZXhpc3RzKVxuICAgIC8vIDIuIE1pbGVzdG9uZSBhc3Nlc3NtZW50IGlzIGNvbXBsZXRlZCAob3Igbm8gYXNzZXNzbWVudCBleGlzdHMpXG4gICAgY29uc3QgbWFuZGF0b3J5Q2hlY2sgPSAhaGFzTWFuZGF0b3J5Q29udGVudCB8fCBhbGxNYW5kYXRvcnlDb21wbGV0ZVxuICAgIGNvbnN0IGFzc2Vzc21lbnRDaGVjayA9ICFoYXNNaWxlc3RvbmVBc3Nlc3NtZW50IHx8IG1pbGVzdG9uZUFzc2Vzc21lbnRDb21wbGV0ZVxuXG4gICAgcmV0dXJuIG1hbmRhdG9yeUNoZWNrICYmIGFzc2Vzc21lbnRDaGVja1xuICB9XG5cbiAgb3BlbkNlcnRpZmljYXRlRGlhbG9nKGNlcnREYXRhOiBhbnkpIHtcbiAgICBjb25zdCBjZXQgPSBjZXJ0RGF0YVxuICAgIHRoaXMuZGlhbG9nLm9wZW4oQ2VydGlmaWNhdGVEaWFsb2dDb21wb25lbnQsIHtcbiAgICAgIC8vIGhlaWdodDogJzQwMHB4JyxcbiAgICAgIHdpZHRoOiAnMTMwMHB4JyxcbiAgICAgIGRhdGE6IHsgY2V0IH0sXG4gICAgICAvLyBwYW5lbENsYXNzOiAnY3VzdG9tLWRpYWxvZy1jb250YWluZXInLFxuICAgIH0pXG4gIH1cbiAgc2Nyb2xsVmlldygpIHtcbiAgICB0cnkge1xuICAgICAgbGV0IGVycm9yRmllbGQ6IGFueSA9IHRoaXMucmVuZGVyZXIuc2VsZWN0Um9vdEVsZW1lbnQoJy5yZXNvdXJjZS1jb250YWluZXIgLnJlc291cmNlLWFjdGl2ZScpXG4gICAgICBpZiAoZXJyb3JGaWVsZCkge1xuICAgICAgICBlcnJvckZpZWxkLnNjcm9sbEludG9WaWV3KHsgYmVoYXZpb3I6IFwic21vb3RoXCIsIGJsb2NrOiBcInN0YXJ0XCIsIGlubGluZTogXCJuZWFyZXN0XCIgfSlcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmNvbXBvbmVudE5hbWUgPT09ICd0b2MnKSB7XG4gICAgICAgIGlmIChlcnJvckZpZWxkKSB7XG4gICAgICAgICAgY29uc3QgcmVjdCA9IGVycm9yRmllbGQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgICAgICAgICBpZiAocmVjdC50b3AgLSA0MjAgPiAwKSB7XG4gICAgICAgICAgICB3aW5kb3cuc2Nyb2xsKDQyMCwgcmVjdC50b3AgLSAxNDgpXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5hcHBUb2NTdmMuZ2V0UGFnZVNjcm9sbC5uZXh0KGZhbHNlKVxuICAgICAgfSwgNzAwKVxuXG4gICAgICAvLyBlbHNlIHtcbiAgICAgIC8vICAgZXJyb3JGaWVsZC5zY3JvbGxJbnRvVmlldyh7IGJlaGF2aW9yOiBcInNtb290aFwiLCBibG9jazogXCJzdGFydFwiLCBpbmxpbmU6IFwibmVhcmVzdFwiIH0pO1xuICAgICAgLy8gICBjb25zdCByZWN0ID0gZXJyb3JGaWVsZC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIC8vICAgZXJyb3JGaWVsZC5zY3JvbGwoMCxyZWN0LnRvcC01NilcbiAgICAgIC8vIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICB9XG4gIH1cblxuICBkb3dubG9hZENlcnRpZmljYXRlKGNlcnRpZmljYXRlRGF0YTogYW55KSB7XG4gICAgXG4gICAgdGhpcy5ldmVudHMucmFpc2VJbnRlcmFjdFRlbGVtZXRyeShcbiAgICAgIHtcbiAgICAgICAgdHlwZTogV3NFdmVudHMuRW51bUludGVyYWN0VHlwZXMuQ0xJQ0ssXG4gICAgICAgIGlkOiAndmlldy1jZXJ0aWZpY2F0ZScsXG4gICAgICAgIHN1YlR5cGU6IFdzRXZlbnRzLkVudW1JbnRlcmFjdFN1YlR5cGVzLkNFUlRJRklDQVRFLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgaWQ6IGNlcnRpZmljYXRlRGF0YSwgICAvLyBpZCBvZiB0aGUgY2VydGlmaWNhdGVcbiAgICAgICAgdHlwZTogV3NFdmVudHMuRW51bUludGVyYWN0U3ViVHlwZXMuQ0VSVElGSUNBVEUsXG4gICAgICB9KVxuICAgIGlmIChjZXJ0aWZpY2F0ZURhdGEpIHtcbiAgICAgIHRoaXMuZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmcgPSB0cnVlXG4gICAgICBsZXQgY2VydERhdGE6IGFueSA9IGNlcnRpZmljYXRlRGF0YSB8fCBjZXJ0aWZpY2F0ZURhdGEuaWRlbnRpZmllclxuICAgICAgdGhpcy5jZXJ0aWZpY2F0ZVNlcnZpY2UuZG93bmxvYWRDZXJ0aWZpY2F0ZV92MyhjZXJ0RGF0YSkuc3Vic2NyaWJlKChyZXM6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLmRvd25sb2FkQ2VydGlmaWNhdGVMb2FkaW5nID0gZmFsc2VcbiAgICAgICAgY29uc3QgY2V0ID0gcmVzLnJlc3VsdC5wcmludFVyaVxuICAgICAgICB0aGlzLmRpYWxvZy5vcGVuKENlcnRpZmljYXRlRGlhbG9nQ29tcG9uZW50LCB7XG4gICAgICAgICAgd2lkdGg6ICcxMzAwcHgnLFxuICAgICAgICAgIGRhdGE6IHsgY2V0LCBjZXJ0SWQ6IGNlcnREYXRhIH0sXG4gICAgICAgIH0pXG4gICAgICB9KVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRvd25sb2FkQ2VydGlmaWNhdGVMb2FkaW5nID0gZmFsc2VcbiAgICB9XG4gIH1cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgaWYgKHRoaXMuaGFzaG1hcFVwZGF0ZWRTdWJzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMuaGFzaG1hcFVwZGF0ZWRTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKVxuICAgIH1cbiAgICBpZiAodGhpcy5wYWdlU2Nyb2xsU3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLnBhZ2VTY3JvbGxTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKVxuICAgIH1cbiAgfVxuXG4gIGdldCBjaGVja0ZvckN1cmF0ZWRQcm9ncmFtKCkge1xuICAgIGlmICh0aGlzLl9jYWNoZUluaXRpYWxpemVkKSB7XG4gICAgICByZXR1cm4gdGhpcy5fY2FjaGVkQ2hlY2tGb3JDdXJhdGVkUHJvZ3JhbVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jb21wdXRlQ2hlY2tGb3JDdXJhdGVkUHJvZ3JhbSgpXG4gIH1cblxuICBnZXQgaXNDb250ZW50VW5sb2NrZWQoKSB7XG4gICAgaWYgKHRoaXMuX2NhY2hlSW5pdGlhbGl6ZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLl9jYWNoZWRJc0NvbnRlbnRVbmxvY2tlZFxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jb21wdXRlSXNDb250ZW50VW5sb2NrZWQoKVxuICB9XG5cbiAgZ2V0IGlzUGFyZW50TWlsZXN0b25lTG9ja2VkKCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLl9jYWNoZUluaXRpYWxpemVkKSB7XG4gICAgICByZXR1cm4gdGhpcy5fY2FjaGVkSXNQYXJlbnRNaWxlc3RvbmVMb2NrZWRcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY29tcHV0ZUlzUGFyZW50TWlsZXN0b25lTG9ja2VkKClcbiAgfVxuXG4gIGdldCBpc01pbGVzdG9uZUxvY2tlZCgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5fY2FjaGVJbml0aWFsaXplZCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZElzTWlsZXN0b25lTG9ja2VkXG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNvbXB1dGVJc01pbGVzdG9uZUxvY2tlZCgpXG4gIH1cblxuICBnZXQgaXNNaWxlc3RvbmVBc3Nlc3NtZW50KCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLl9jYWNoZUluaXRpYWxpemVkKSB7XG4gICAgICByZXR1cm4gdGhpcy5fY2FjaGVkSXNNaWxlc3RvbmVBc3Nlc3NtZW50XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNvbXB1dGVJc01pbGVzdG9uZUFzc2Vzc21lbnQoKVxuICB9XG5cbiAgZ2V0IGlzTWlsZXN0b25lQXNzZXNzbWVudExvY2tlZCgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5fY2FjaGVJbml0aWFsaXplZCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZElzTWlsZXN0b25lQXNzZXNzbWVudExvY2tlZFxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jb21wdXRlSXNNaWxlc3RvbmVBc3Nlc3NtZW50TG9ja2VkKClcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhIG1pbGVzdG9uZSdzIG1hbmRhdG9yeSBjb3Vyc2VzIGFuZCBhc3Nlc3NtZW50IGFyZSBjb21wbGV0ZWQuXG4gICAqIExvb2tzIGF0IHRoZSBjb250ZW50IGhpZXJhcmNoeSB0byBmaW5kIGNoaWxkcmVuIG9mIHRoZSBtaWxlc3RvbmUuXG4gICAqL1xuICBwcml2YXRlIGNoZWNrTWlsZXN0b25lQ29udGVudENvbXBsZXRpb24obWlsZXN0b25lSWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmICghdGhpcy5iYXNlQ29udGVudFJlYWREYXRhIHx8ICF0aGlzLmJhc2VDb250ZW50UmVhZERhdGEuY2hpbGRyZW4gfHwgIXRoaXMuaGllcmFyY2h5TWFwRGF0YSkge1xuICAgICAgLy8gRmFsbGJhY2s6IFRyeSB0byBmaW5kIGFzc2Vzc21lbnQgY29tcGxldGlvbiBpbiBoYXNobWFwIGZvciB0aGlzIG1pbGVzdG9uZVxuICAgICAgcmV0dXJuIHRoaXMuY2hlY2tNaWxlc3RvbmVBc3Nlc3NtZW50Q29tcGxldGlvbihtaWxlc3RvbmVJZClcbiAgICB9XG5cbiAgICAvLyBGaW5kIHRoZSBtaWxlc3RvbmUgaW4gdGhlIGNvbnRlbnQgaGllcmFyY2h5XG4gICAgY29uc3QgbWlsZXN0b25lQ29udGVudCA9IHRoaXMuZmluZENvbnRlbnRJbkhpZXJhcmNoeSh0aGlzLmJhc2VDb250ZW50UmVhZERhdGEsIG1pbGVzdG9uZUlkKVxuICAgIGlmICghbWlsZXN0b25lQ29udGVudCB8fCAhbWlsZXN0b25lQ29udGVudC5jaGlsZHJlbikge1xuICAgICAgcmV0dXJuIHRoaXMuY2hlY2tNaWxlc3RvbmVBc3Nlc3NtZW50Q29tcGxldGlvbihtaWxlc3RvbmVJZClcbiAgICB9XG5cbiAgICAvLyBDaGVjayBhbGwgbWFuZGF0b3J5IGNvdXJzZXMgYW5kIGFzc2Vzc21lbnRzXG4gICAgbGV0IGFsbE1hbmRhdG9yeUNvbXBsZXRlID0gdHJ1ZVxuICAgIGxldCBoYXNBc3Nlc3NtZW50ID0gZmFsc2VcbiAgICBsZXQgYXNzZXNzbWVudENvbXBsZXRlID0gZmFsc2VcblxuICAgIG1pbGVzdG9uZUNvbnRlbnQuY2hpbGRyZW4uZm9yRWFjaCgoY2hpbGQ6IGFueSkgPT4ge1xuICAgICAgY29uc3QgY2hpbGREYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW2NoaWxkLmlkZW50aWZpZXJdXG4gICAgICBjb25zdCBpc0Fzc2Vzc21lbnQgPSBjaGlsZC5wcmltYXJ5Q2F0ZWdvcnkgPT09ICdDb3Vyc2UgQXNzZXNzbWVudCcgfHxcbiAgICAgICAgY2hpbGQuY291cnNlQ2F0ZWdvcnkgPT09ICdDb3Vyc2UgQXNzZXNzbWVudCcgfHxcbiAgICAgICAgY2hpbGQucHJpbWFyeUNhdGVnb3J5ID09PSAnRmluYWwgQXNzZXNzbWVudCdcbiAgICAgIGNvbnN0IGlzTWFuZGF0b3J5ID0gY2hpbGQubWFuZGF0b3J5ID09PSB0cnVlIHx8IGNoaWxkLm9wdGlvbmFsUmVhZGluZyAhPT0gdHJ1ZVxuXG4gICAgICBpZiAoaXNBc3Nlc3NtZW50KSB7XG4gICAgICAgIGhhc0Fzc2Vzc21lbnQgPSB0cnVlXG4gICAgICAgIGlmIChjaGlsZERhdGEgJiYgKGNoaWxkRGF0YS5jb21wbGV0aW9uU3RhdHVzID09PSAyIHx8IGNoaWxkRGF0YS5jb21wbGV0aW9uUGVyY2VudGFnZSA+PSAxMDApKSB7XG4gICAgICAgICAgYXNzZXNzbWVudENvbXBsZXRlID0gdHJ1ZVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGlzTWFuZGF0b3J5KSB7XG4gICAgICAgIC8vIENoZWNrIGlmIG1hbmRhdG9yeSBjb250ZW50IGlzIGNvbXBsZXRlZFxuICAgICAgICBpZiAoIWNoaWxkRGF0YSB8fCAoY2hpbGREYXRhLmNvbXBsZXRpb25TdGF0dXMgIT09IDIgJiYgY2hpbGREYXRhLmNvbXBsZXRpb25QZXJjZW50YWdlIDwgMTAwKSkge1xuICAgICAgICAgIGFsbE1hbmRhdG9yeUNvbXBsZXRlID0gZmFsc2VcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pXG5cblxuICAgIC8vIE1pbGVzdG9uZSBpcyBjb21wbGV0ZSBpZiBhc3Nlc3NtZW50IGlzIGNvbXBsZXRlIChtYW5kYXRvcnkgY291cnNlcyBvcHRpb25hbCBiYXNlZCBvbiByZXF1aXJlbWVudHMpXG4gICAgcmV0dXJuIGhhc0Fzc2Vzc21lbnQgPyBhc3Nlc3NtZW50Q29tcGxldGUgOiBhbGxNYW5kYXRvcnlDb21wbGV0ZVxuICB9XG5cbiAgLyoqXG4gICAqIEZhbGxiYWNrOiBDaGVjayBpZiBlbm91Z2ggYXNzZXNzbWVudHMgYXJlIGNvbXBsZXRlZCB0byB1bmxvY2sgdGhpcyBtaWxlc3RvbmUuXG4gICAqIEZvciBtaWxlc3RvbmUgYXQgaW5kZXggTiwgd2UgbmVlZCBhdCBsZWFzdCBOIGNvbXBsZXRlZCBhc3Nlc3NtZW50cy5cbiAgICogRS5nLiwgRm9yIE0yIChpbmRleCAxKSwgd2UgbmVlZCAxIGNvbXBsZXRlZCBhc3Nlc3NtZW50IChNMSdzIGFzc2Vzc21lbnQpXG4gICAqICAgICAgIEZvciBNMyAoaW5kZXggMiksIHdlIG5lZWQgMiBjb21wbGV0ZWQgYXNzZXNzbWVudHMgKE0xJ3MgYW5kIE0yJ3MpXG4gICAqL1xuICBwcml2YXRlIGNoZWNrTWlsZXN0b25lQXNzZXNzbWVudENvbXBsZXRpb24obWlsZXN0b25lSWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmICghdGhpcy5oaWVyYXJjaHlNYXBEYXRhKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICAvLyBFeHRyYWN0IG1pbGVzdG9uZSBudW1iZXIgZnJvbSBJRCAoTTEgLT4gMSwgTTIgLT4gMiwgZXRjLilcbiAgICBjb25zdCBtaWxlc3RvbmVOdW0gPSBwYXJzZUludChtaWxlc3RvbmVJZC5yZXBsYWNlKC9cXEQvZywgJycpKSB8fCAwXG4gICAgY29uc3QgcmVxdWlyZWRDb21wbGV0ZWRBc3Nlc3NtZW50cyA9IG1pbGVzdG9uZU51bSAtIDEgLy8gRm9yIE0yLCBuZWVkIDE7IGZvciBNMywgbmVlZCAyXG5cblxuICAgIGlmIChyZXF1aXJlZENvbXBsZXRlZEFzc2Vzc21lbnRzIDw9IDApIHtcbiAgICAgIHJldHVybiB0cnVlIC8vIEZpcnN0IG1pbGVzdG9uZSwgbm8gcmVxdWlyZW1lbnRzXG4gICAgfVxuXG4gICAgLy8gQ291bnQgY29tcGxldGVkIENvdXJzZSBBc3Nlc3NtZW50cyB0aGF0IGFyZSBJTlNJREUgbWlsZXN0b25lcyAoaGF2ZSBhIHBhcmVudClcbiAgICAvLyBFeGNsdWRlIHByZS1lbnJvbGxtZW50IGFzc2Vzc21lbnRzIGF0IHRoZSByb290IGxldmVsIChubyBwYXJlbnQgb3IgcGFyZW50IGlzIExlYXJuaW5nIFBhdGh3YXkpXG4gICAgbGV0IGNvbXBsZXRlZE1pbGVzdG9uZUFzc2Vzc21lbnRDb3VudCA9IDBcbiAgICBjb25zdCBsZWFybmluZ1BhdGh3YXlJZCA9IHRoaXMuYmFzZUNvbnRlbnRSZWFkRGF0YT8uaWRlbnRpZmllclxuXG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXModGhpcy5oaWVyYXJjaHlNYXBEYXRhKSkge1xuICAgICAgY29uc3QgaXRlbSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YVtrZXldXG5cbiAgICAgIC8vIENoZWNrIGlmIGl0J3MgYSBjb21wbGV0ZWQgQ291cnNlIEFzc2Vzc21lbnRcbiAgICAgIGlmICgoaXRlbS5wcmltYXJ5Q2F0ZWdvcnkgPT09ICdDb3Vyc2UgQXNzZXNzbWVudCcgfHwgaXRlbS5jb3Vyc2VDYXRlZ29yeSA9PT0gJ0NvdXJzZSBBc3Nlc3NtZW50JykgJiZcbiAgICAgICAgKGl0ZW0uY29tcGxldGlvblN0YXR1cyA9PT0gMiB8fCBpdGVtLmNvbXBsZXRpb25QZXJjZW50YWdlID49IDEwMCkpIHtcblxuICAgICAgICAvLyBDaGVjayBpZiB0aGlzIGFzc2Vzc21lbnQgaGFzIGEgcGFyZW50IChtZWFuaW5nIGl0J3MgaW5zaWRlIGEgY291cnNlL21pbGVzdG9uZSwgbm90IGF0IHJvb3QgbGV2ZWwpXG4gICAgICAgIC8vIEFsc28gZXhjbHVkZSBpZiBwYXJlbnQgaXMgdGhlIExlYXJuaW5nIFBhdGh3YXkgaXRzZWxmIChwcmUtZW5yb2xsbWVudCBhc3Nlc3NtZW50KVxuICAgICAgICBjb25zdCBoYXNQYXJlbnQgPSBpdGVtLnBhcmVudCAmJiBpdGVtLnBhcmVudCAhPT0gbGVhcm5pbmdQYXRod2F5SWRcblxuICAgICAgICBpZiAoaGFzUGFyZW50KSB7XG4gICAgICAgICAgY29tcGxldGVkTWlsZXN0b25lQXNzZXNzbWVudENvdW50KytcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBJZiB3ZSBoYXZlIGVub3VnaCBjb21wbGV0ZWQgbWlsZXN0b25lIGFzc2Vzc21lbnRzLCB1bmxvY2sgdGhpcyBtaWxlc3RvbmVcbiAgICByZXR1cm4gY29tcGxldGVkTWlsZXN0b25lQXNzZXNzbWVudENvdW50ID49IHJlcXVpcmVkQ29tcGxldGVkQXNzZXNzbWVudHNcbiAgfVxuXG4gIHByaXZhdGUgZmluZENvbnRlbnRJbkhpZXJhcmNoeShjb250ZW50OiBhbnksIGlkZW50aWZpZXI6IHN0cmluZyk6IGFueSB7XG4gICAgaWYgKCFjb250ZW50KSByZXR1cm4gbnVsbFxuICAgIGlmIChjb250ZW50LmlkZW50aWZpZXIgPT09IGlkZW50aWZpZXIpIHJldHVybiBjb250ZW50XG4gICAgaWYgKGNvbnRlbnQuY2hpbGRyZW4pIHtcbiAgICAgIGZvciAoY29uc3QgY2hpbGQgb2YgY29udGVudC5jaGlsZHJlbikge1xuICAgICAgICBjb25zdCBmb3VuZCA9IHRoaXMuZmluZENvbnRlbnRJbkhpZXJhcmNoeShjaGlsZCwgaWRlbnRpZmllcilcbiAgICAgICAgaWYgKGZvdW5kKSByZXR1cm4gZm91bmRcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIGdldCBjb21wdXRlZFF1ZXJ5UGFyYW1zKCkge1xuICAgIGlmICh0aGlzLmlzQWxsb3dlZCAmJiAhdGhpcy5mb3JQcmV2aWV3ICYmIHRoaXMuaXNFbmFibGVkKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi50aGlzLnJlc291cmNlTGluay5xdWVyeVBhcmFtcyxcbiAgICAgICAgcHJlQXNzZXNzbWVudDogJ3RydWUnXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsXG4gIH1cblxuICBnZXQgaXNNaWxlc3RvbmUoKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMuX2NhY2hlSW5pdGlhbGl6ZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLl9jYWNoZWRJc01pbGVzdG9uZVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jb21wdXRlSXNNaWxlc3RvbmUoKVxuICB9XG5cbiAgZ2V0TWlsZXN0b25lQ29tcGxldGVkQ291bnQoKTogbnVtYmVyIHtcbiAgICBpZiAodGhpcy5fY2FjaGVJbml0aWFsaXplZCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZE1pbGVzdG9uZUNvbXBsZXRlZENvdW50XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNvbXB1dGVNaWxlc3RvbmVDb21wbGV0ZWRDb3VudCgpXG4gIH1cblxuICBwcml2YXRlIGNvbXB1dGVNaWxlc3RvbmVDb21wbGV0ZWRDb3VudCgpOiBudW1iZXIge1xuICAgIGlmICghdGhpcy5jb250ZW50IHx8ICF0aGlzLmhpZXJhcmNoeU1hcERhdGEpIHtcbiAgICAgIHJldHVybiAwXG4gICAgfVxuICAgIGNvbnN0IG1pbGVzdG9uZURhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbdGhpcy5jb250ZW50LmlkZW50aWZpZXJdXG4gICAgaWYgKCFtaWxlc3RvbmVEYXRhIHx8ICFtaWxlc3RvbmVEYXRhLmxlYWZOb2Rlcykge1xuICAgICAgcmV0dXJuIDBcbiAgICB9XG4gICAgXG4gICAgbGV0IGNvbXBsZXRlZENvdW50ID0gMFxuICAgIFxuICAgIG1pbGVzdG9uZURhdGEubGVhZk5vZGVzLmZvckVhY2goKGxlYWZJZDogc3RyaW5nKSA9PiB7XG4gICAgICBjb25zdCBsZWFmRGF0YSA9IHRoaXMuaGllcmFyY2h5TWFwRGF0YVtsZWFmSWRdXG4gICAgICBpZiAobGVhZkRhdGEpIHtcbiAgICAgICAgLy8gQ1JJVElDQUw6IENoZWNrIG11bHRpcGxlIGNvbXBsZXRpb24gaW5kaWNhdG9yc1xuICAgICAgICBjb25zdCBpc0NvbXBsZXRlZCA9IFxuICAgICAgICAgIGxlYWZEYXRhLmNvbXBsZXRpb25TdGF0dXMgPT09IDIgfHwgXG4gICAgICAgICAgbGVhZkRhdGEuc3RhdHVzID09PSAyIHx8IFxuICAgICAgICAgIChsZWFmRGF0YS5jb21wbGV0aW9uUGVyY2VudGFnZSAmJiBsZWFmRGF0YS5jb21wbGV0aW9uUGVyY2VudGFnZSA+PSAxMDApIHx8XG4gICAgICAgICAgKGxlYWZEYXRhLnByb2dyZXNzICYmIGxlYWZEYXRhLnByb2dyZXNzID49IDEwMClcbiAgICAgICAgXG4gICAgICAgIGlmIChpc0NvbXBsZXRlZCkge1xuICAgICAgICAgIGNvbXBsZXRlZENvdW50KytcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pXG4gICAgXG4gICAgcmV0dXJuIGNvbXBsZXRlZENvdW50XG4gIH1cblxuICAvKipcbiAgICogR2V0IHVubG9jayBjcml0ZXJpYSBtZXNzYWdlIGZvciBsb2NrZWQgbWlsZXN0b25lc1xuICAgKi9cbiAgZ2V0TWlsZXN0b25lVW5sb2NrTWVzc2FnZSgpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5jb250ZW50IHx8ICF0aGlzLmhpZXJhcmNoeU1hcERhdGEpIHtcbiAgICAgIHJldHVybiAnJ1xuICAgIH1cblxuICAgIGNvbnN0IG1pbGVzdG9uZURhdGEgPSB0aGlzLmhpZXJhcmNoeU1hcERhdGFbdGhpcy5jb250ZW50LmlkZW50aWZpZXJdXG4gICAgaWYgKCFtaWxlc3RvbmVEYXRhKSB7XG4gICAgICByZXR1cm4gJydcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiBoYXNobWFwIGhhcyBwcmUtY29tcHV0ZWQgdW5sb2NrIG1lc3NhZ2VcbiAgICBpZiAobWlsZXN0b25lRGF0YS51bmxvY2tNZXNzYWdlKSB7XG4gICAgICByZXR1cm4gbWlsZXN0b25lRGF0YS51bmxvY2tNZXNzYWdlXG4gICAgfVxuXG4gICAgY29uc3QgbWlsZXN0b25lSW5kZXggPSBtaWxlc3RvbmVEYXRhLm1pbGVzdG9uZUluZGV4XG5cbiAgICAvLyBNaWxlc3RvbmUgMSByZXF1aXJlcyBwcmUtYXNzZXNzbWVudCBjb21wbGV0aW9uXG4gICAgaWYgKG1pbGVzdG9uZUluZGV4ID09PSAwKSB7XG4gICAgICByZXR1cm4gJ0NvbXBsZXRlIHRoZSBwcmVsaW1pbmFyeSBhc3Nlc3NtZW50IHRvIHVubG9jayB0aGlzIG1pbGVzdG9uZSdcbiAgICB9XG5cbiAgICAvLyBPdGhlciBtaWxlc3RvbmVzIHJlcXVpcmUgcHJldmlvdXMgbWlsZXN0b25lIGNvbXBsZXRpb25cbiAgICByZXR1cm4gYENvbXBsZXRlIGFsbCBtYW5kYXRvcnkgY29udGVudCBhbmQgYXNzZXNzbWVudCBpbiBNaWxlc3RvbmUgJHttaWxlc3RvbmVJbmRleH0gdG8gdW5sb2NrIHRoaXMgbWlsZXN0b25lYFxuICB9XG5cbiAgLyoqXG4gICAqIEdldCBsb2NrIG1lc3NhZ2UgZm9yIGNvbnRlbnQgaW5zaWRlIGxvY2tlZCBtaWxlc3RvbmVzXG4gICAqL1xuICBnZXRQYXJlbnRNaWxlc3RvbmVMb2NrTWVzc2FnZSgpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5pc1BhcmVudE1pbGVzdG9uZUxvY2tlZCkge1xuICAgICAgcmV0dXJuICcnXG4gICAgfVxuICAgIHJldHVybiAnVGhpcyBjb250ZW50IGlzIGxvY2tlZC4gQ29tcGxldGUgcHJldmlvdXMgbWlsZXN0b25lIHRvIHZpZXcgdGhpcyBjb250ZW50LidcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgbG9jayBtZXNzYWdlIGZvciBtaWxlc3RvbmUgYXNzZXNzbWVudHNcbiAgICovXG4gIGdldEFzc2Vzc21lbnRMb2NrTWVzc2FnZSgpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5jb250ZW50IHx8ICF0aGlzLmhpZXJhcmNoeU1hcERhdGEpIHtcbiAgICAgIHJldHVybiAnJ1xuICAgIH1cblxuICAgIGNvbnN0IGhhc2hEYXRhID0gdGhpcy5oaWVyYXJjaHlNYXBEYXRhW3RoaXMuY29udGVudC5pZGVudGlmaWVyXVxuICAgIFxuICAgIC8vIENoZWNrIGlmIGhhc2htYXAgaGFzIHByZS1jb21wdXRlZCBhc3Nlc3NtZW50IGxvY2sgbWVzc2FnZVxuICAgIGlmIChoYXNoRGF0YSAmJiBoYXNoRGF0YS5hc3Nlc3NtZW50TG9ja01lc3NhZ2UpIHtcbiAgICAgIHJldHVybiBoYXNoRGF0YS5hc3Nlc3NtZW50TG9ja01lc3NhZ2VcbiAgICB9XG5cbiAgICBpZiAodGhpcy5pc01pbGVzdG9uZUFzc2Vzc21lbnRMb2NrZWQpIHtcbiAgICAgIHJldHVybiAnVGhpcyBjb250ZW50IGlzIGxvY2tlZC4gQ29tcGxldGUgYWxsIG1hbmRhdG9yeSBpdGVtcyB0byB1bmxvY2sgdGhlIGFzc2Vzc21lbnQuJ1xuICAgIH1cblxuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgc2hvdWxkU2hvd0Rvd25sb2FkQnV0dG9uKGNvbnRlbnQ6IE5zQ29udGVudC5JQ29udGVudCB8IG51bGwpOiBib29sZWFuIHtcbiAgICBpZiAoIWNvbnRlbnQpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIC8vIENoZWNrIGlmIGNvbnRlbnQgaGFzIGFuIGFydGlmYWN0IFVSTCAoZG93bmxvYWRhYmxlIHJlc291cmNlKVxuICAgIGlmICghY29udGVudC5hcnRpZmFjdFVybCkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgYmFzZSBjb250ZW50IHJlc291cmNlIGNhdGVnb3J5IGluY2x1ZGVzIFwiQ2FzZSBTdHVkeVwiXG4gICAgaWYgKCF0aGlzLmJhc2VDb250ZW50UmVhZERhdGE/LmNvdXJzZUNhdGVnb3J5IHx8XG4gICAgICB0aGlzLmJhc2VDb250ZW50UmVhZERhdGEuY291cnNlQ2F0ZWdvcnkgIT09IE5zQ29udGVudC5FQ291cnNlQ2F0ZWdvcnkuQ0FTRV9TVFVEWSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy9mb3IgcHVibGljIHNjZW5hcmlvIGNoZWNrIGlmIGl0cyBwbGF5ZXIgcGxhZ2UgdGhlbiBvbmx5IGVuYWJsZSBkb3dubG9hZFxuICAgIGlmICh0aGlzLmZvclByZXZpZXcgJiYgIXdpbmRvdy5sb2NhdGlvbi5ocmVmLmluY2x1ZGVzKCcvdmlld2VyLycpKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICAvLyBmb3IgbG9nZ2VkIGluIHVzZXIgY2hlY2sgaWYgdXNlciBlbnJvbGxlZCB0aGVuIG9ubHkgYWxsb3cgZG93bmxvYWRcbiAgICBpZiAoIXRoaXMuZm9yUHJldmlldyAmJiAhdGhpcy5pc0Vucm9sbGVkKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICAvLyBEZWZpbmUgZG93bmxvYWRhYmxlIE1JTUUgdHlwZXNcbiAgICBjb25zdCBkb3dubG9hZGFibGVNaW1lVHlwZXMgPSBbXG4gICAgICBOc0NvbnRlbnQuRU1pbWVUeXBlcy5QREZcbiAgICBdXG5cbiAgICByZXR1cm4gZG93bmxvYWRhYmxlTWltZVR5cGVzLmluY2x1ZGVzKGNvbnRlbnQubWltZVR5cGUpXG4gIH1cblxuICBkb3dubG9hZENvbnRlbnQoY29udGVudDogTnNDb250ZW50LklDb250ZW50LCBldmVudD86IE1vdXNlRXZlbnQpIHtcbiAgICBpZiAoZXZlbnQpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KClcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXG4gICAgfVxuICAgIGNvbnN0IHBhZ2VJZCA9IGBhcHAvdG9jL3BhZ2VJZC8ke2NvbnRlbnQuaWRlbnRpZmllcn1gXG4gICAgdGhpcy5yZXNvdXJjZURvd25sb2FkSGVscGVyU3ZjLmRvd25sb2FkUERGKGNvbnRlbnQsIHBhZ2VJZClcbiAgfVxuXG5cblxuICAvKipcbiAgICogVmlldyBtaWxlc3RvbmUgYWNoaWV2ZW1lbnQgLSBjYWxscyB0aGUgYWNoaWV2ZW1lbnQgQVBJIGFuZCBzaG93cyB0aGUgcmVzdWx0XG4gICAqL1xuICB2aWV3TWlsZXN0b25lQWNoaWV2ZW1lbnQoZXZlbnQ6IE1vdXNlRXZlbnQsIG1pbGVTdG9uZURhdGE6IGFueSkge1xuICAgIFxuICAgIGlmIChldmVudCkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKVxuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuY29udGVudCB8fCAhdGhpcy5iYXRjaElkIHx8IHRoaXMuYWNoaWV2ZW1lbnRMb2FkaW5nKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBHZXQgdXNlciBJRCBmcm9tIENvbmZpZ3VyYXRpb25zU2VydmljZVxuICAgIGNvbnN0IHVzZXJJZCA9IHRoaXMuY29uZmlnU3ZjPy51c2VyUHJvZmlsZT8udXNlcklkXG4gICAgaWYgKCF1c2VySWQpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8vIEV4dHJhY3QgbWlsZXN0b25lIElEIChlLmcuLCBcIm0xXCIsIFwibTJcIikgZnJvbSB0aGUgY29udGVudCBuYW1lIG9yIGluZGV4XG4gICAgLy8gVHJ5IHRvIGdldCBtaWxlc3RvbmUgbnVtYmVyIGZyb20gdGhlIGluZGV4IG9yIGV4dHJhY3QgZnJvbSBjb250ZW50XG4gICAgbGV0IG1pbGVzdG9uZUlkID0gJ20nICsgKHRoaXMuaW5kZXggLSAxKSAvLyBpbmRleCBpcyB0eXBpY2FsbHkgMS1iYXNlZCwgbWlsZXN0b25lcyBhcmUgMC1iYXNlZFxuXG4gICAgLy8gSWYgY29udGVudCBuYW1lIGNvbnRhaW5zIG1pbGVzdG9uZSBudW1iZXIsIGV4dHJhY3QgaXRcbiAgICBpZiAodGhpcy5jb250ZW50Lm5hbWUpIHtcbiAgICAgICAgbWlsZXN0b25lSWQgPSBtaWxlU3RvbmVEYXRhPy5pZGVudGlmaWVyXG4gICAgfVxuXG4gICAgY29uc3QgY291cnNlSWQgPSB0aGlzLmJhc2VDb250ZW50UmVhZERhdGE/LmlkZW50aWZpZXIgfHwgdGhpcy5yb290SWRcblxuICAgIHRoaXMuYWNoaWV2ZW1lbnRMb2FkaW5nID0gdHJ1ZVxuXG4gICAgdGhpcy5hcHBUb2NTdmMuZ2VuZXJhdGVNaWxlc3RvbmVBY2hpZXZlbWVudCh1c2VySWQsIGNvdXJzZUlkLCB0aGlzLmJhdGNoSWQsIG1pbGVzdG9uZUlkKS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKHJlc3BvbnNlOiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy5hY2hpZXZlbWVudExvYWRpbmcgPSBmYWxzZVxuICAgICAgICAvLyBTaG93IGFjaGlldmVtZW50IGRpYWxvZyBvciBoYW5kbGUgcmVzcG9uc2VcbiAgICAgICAgaWYgKHJlc3BvbnNlICYmIHJlc3BvbnNlLnJlc3VsdCkge1xuICAgICAgICAgIC8vIE9wZW4gYSBkaWFsb2cgdG8gc2hvdyB0aGUgYWNoaWV2ZW1lbnRcbiAgICAgICAgICB0aGlzLmRpYWxvZy5vcGVuKENlcnRpZmljYXRlRGlhbG9nQ29tcG9uZW50LCB7XG4gICAgICAgICAgICB3aWR0aDogJzEzMDBweCcsXG4gICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgIGNldDogcmVzcG9uc2UucmVzdWx0LnByaW50VXJpIHx8IHJlc3BvbnNlLnJlc3VsdC5zdmdEYXRhLFxuICAgICAgICAgICAgICBjZXJ0SWQ6IHJlc3BvbnNlPy5yZXN1bHQ/LmlkZW50aWZpZXIgfHwgbWlsZXN0b25lSWQsXG4gICAgICAgICAgICAgIGlzQWNoaWV2ZW1lbnQ6IHRydWVcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGVycm9yOiAoZXJyb3I6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLmFjaGlldmVtZW50TG9hZGluZyA9IGZhbHNlXG4gICAgICAgIC8vIFNob3cgZXJyb3IgbWVzc2FnZSBpbiBzbmFja2JhclxuICAgICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBlcnJvcj8uZXJyb3I/LnJlc3VsdD8ubWVzc2FnZSB8fCBlcnJvcj8ubWVzc2FnZSB8fCAnRmFpbGVkIHRvIGdlbmVyYXRlIGFjaGlldmVtZW50J1xuICAgICAgICB0aGlzLnNuYWNrQmFyLm9wZW4oZXJyb3JNZXNzYWdlLCAnQ2xvc2UnLCB7XG4gICAgICAgICAgZHVyYXRpb246IDUwMDAsXG4gICAgICAgICAgaG9yaXpvbnRhbFBvc2l0aW9uOiAnY2VudGVyJyxcbiAgICAgICAgICB2ZXJ0aWNhbFBvc2l0aW9uOiAnYm90dG9tJyxcbiAgICAgICAgICBwYW5lbENsYXNzOiBbJ2Vycm9yLXNuYWNrYmFyJ11cbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICB9KVxuICB9XG4gLyoqXG4gICAqIENoZWNrIGlmIHRleHQgaXMgdHJ1bmNhdGVkIChoYXMgZWxsaXBzaXMpIC0gZm9yIHNpbmdsZSBsaW5lIHRleHRcbiAgICogQHBhcmFtIGVsZW1lbnQgVGhlIEhUTUxFbGVtZW50IHRvIGNoZWNrXG4gICAqIEByZXR1cm5zIHRydWUgaWYgdGV4dCBpcyB0cnVuY2F0ZWQsIGZhbHNlIG90aGVyd2lzZVxuICAgKi9cbiAgaXNUZXh0VHJ1bmNhdGVkKGVsZW1lbnQ6IEhUTUxFbGVtZW50KTogYm9vbGVhbiB7XG4gICAgaWYgKCFlbGVtZW50KSByZXR1cm4gZmFsc2VcbiAgICByZXR1cm4gZWxlbWVudC5vZmZzZXRXaWR0aCA8IGVsZW1lbnQuc2Nyb2xsV2lkdGhcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0gZWxlbWVudCBUaGUgSFRNTEVsZW1lbnQgdG8gY2hlY2tcbiAgICogQHJldHVybnMgdHJ1ZSBpZiB0ZXh0IGlzIHRydW5jYXRlZCwgZmFsc2Ugb3RoZXJ3aXNlXG4gICAqL1xuICBpc011bHRpTGluZVRydW5jYXRlZChlbGVtZW50OiBIVE1MRWxlbWVudCk6IGJvb2xlYW4ge1xuICAgIGlmICghZWxlbWVudCkgcmV0dXJuIGZhbHNlXG4gICAgcmV0dXJuIGVsZW1lbnQuc2Nyb2xsSGVpZ2h0ID4gZWxlbWVudC5jbGllbnRIZWlnaHRcbiAgfVxufVxuIiwiPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnQgJiYgIWlzUHJlQXNzZXNzbWVudFwiPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc0NvbGxlY3Rpb24gJiYgIWlzTW9kdWxlXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwiY29sbGVjdGlvblRlbXBsYXRlXCI+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvbmctY29udGFpbmVyPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc0NvbGxlY3Rpb24gJiYgaXNNb2R1bGVcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnQ/Lm1vZHVsZVJlc291cnNlQ291bnRcIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwiY29sbGVjdGlvblRlbXBsYXRlXCI+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8ZGl2ICpuZ0lmPVwiaXNSZXNvdXJjZVwiIGNsYXNzPVwicmVzb3VyY2UtY29udGFpbmVyXCJcbiAgICAgICAgW25nQ2xhc3NdPVwicGF0aFNldD8uaGFzKGNvbnRlbnQ/LmlkZW50aWZpZXIpICYmIGlzRW5yb2xsZWQgPyAnY29udGVudC1hY3RpdmUtcmVzb3VyY2UnOiAnY29udGVudC1ub3QtYWN0aXZlLXJlc291cmNlJ1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwicmVzb3VyY2UgZmxleCAgc206ZmxleC1yb3cgZmxleC1zdGFydCB3aWR0aC1leHBhbmQgdy0xMDAgc206cHItNCBzbTp3LWF1dG9cIlxuICAgICAgICAgICAgW25nQ2xhc3NdPVwieydhY3RpdmVSZXNvdXJjZSc6IHBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKSAmJiBpc0Vucm9sbGVkfVwiPlxuICAgICAgICAgICAgPCEtLSBMb2NrIG1lc3NhZ2UgZm9yIGN1cmF0ZWQgcHJvZ3JhbXMgb25seSAoc2hvd24gYWJvdmUgY29udGVudCkgLS0+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudD8ucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCAmJiBjaGVja0ZvckN1cmF0ZWRQcm9ncmFtICYmXG4gICAgICAgICAgICAhaXNDb250ZW50VW5sb2NrZWRcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29udGVudC1sb2NraW5nIGZsZXggdy1mdWxsIGZsZXgtbWlkZGxlIG1iLTIgZ2FwLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwibG9jay1pY29uXCI+bG9jazwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibG9jay1tZXNzYWdlIG1hdC1ib2R5LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIEtpbmRseSBlbnN1cmUgdGhhdCB5b3UgaGF2ZSBlbnJvbGxlZCBpbiB0aGUgQ29tcHJlaGVuc2l2ZSBBc3Nlc3NtZW50IFByb2dyYW0gYW5kIGNvbXBsZXRlZCBhbGwgdGhlIHJlcXVpcmVkIGNvdXJzZXMgdG8gdW5sb2NrIHRoZSBGaW5hbCBBc3Nlc3NtZW50LlxuICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwhLS0gPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnQ/LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgJiYgY2hlY2tGb3JDdXJhdGVkUHJvZ3JhbSAmJlxuICAgICAgICAgICAgaXNDb250ZW50VW5sb2NrZWRcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29udGVudC1sb2NraW5nIGZsZXggdy1mdWxsIGZsZXgtbWlkZGxlIG1iLTIgZ2FwLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwidW5sb2NrLWljb25cIj5sb2NrX29wZW5fcmlnaHQ8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInVubG9jay1tZXNzYWdlIG1hdC1ib2R5LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMgY29udGVudCBpcyB1bmxvY2tlZC5cbiAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+IC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC13cmFwIGl0ZW1zLXN0YXJ0IGp1c3RpZnktc3RhcnQgc206anVzdGlmeS1lbmRcIj5cbiAgICAgICAgICAgICAgICA8IS0tIDxidXR0b24gKm5nSWY9XCIhZm9yUHJldmlldyAmJiBjb250ZW50Py5hcnRpZmFjdFVybCAmJiAhaXNYU21hbGwgJiYgaXNBbGxvd2VkICYmIGlzRW5hYmxlZFwiIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBtYXQtaWNvbi1idXR0b24gY2xhc3M9XCJcIiBbbWF0TWVudVRyaWdnZXJGb3JdPVwiYnV0dG9uTWVudVwiPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24+bW9yZV92ZXJ0aWNhbDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+IC0tPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc0Vucm9sbGVkICAmJiAhaXNNaWxlc3RvbmVMb2NrZWQgJiYgIWlzUGFyZW50TWlsZXN0b25lTG9ja2VkXCI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIWZvclByZXZpZXcgJiYgIGNvbnRlbnQ/LmlkZW50aWZpZXIgJiYgZ2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcikgOyBlbHNlIGVsc2VCbG9ja1wiPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0Q29tcGxldGlvblN0YXR1cyhjb250ZW50Py5pZGVudGlmaWVyKSA9PSAyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbXBsZXRlZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwiY29tcGxldGVkLWljb25cIiBbY29sb3JdPVwiYmx1ZVwiPmNoZWNrX2NpcmNsZTwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0Q29tcGxldGlvblN0YXR1cyhjb250ZW50Py5pZGVudGlmaWVyKSA8IDJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlLXByb2dyZXNzIGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgcHJvZ3Jlc3NcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGVyY2VudF09XCJnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKVwiIFtyYWRpdXNdPVwiMTBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3V0ZXJTdHJva2VXaWR0aF09XCIyXCIgW2lubmVyU3Ryb2tlV2lkdGhdPVwiMlwiIFtzcGFjZV09XCItMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZUNvbG9yXT1cInByb2dyZXNzQ29sb3IyKClcIiBbaW5uZXJTdHJva2VDb2xvcl09XCIncmdiYSgwLCAwLCAwLCAwLjE2KSdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYW5pbWF0aW9uXT1cInRydWVcIiBbYW5pbWF0aW9uRHVyYXRpb25dPVwiMjUwXCIgW3Nob3dUaXRsZV09XCJmYWxzZVwiIFtzaG93VW5pdHNdPVwiZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2hvd1N1YnRpdGxlXT1cImZhbHNlXCIgW3Nob3dJbm5lclN0cm9rZV09XCJ0cnVlXCIgW2Nsb2Nrd2lzZV09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2JhY2tncm91bmRPcGFjaXR5XT1cIjBcIiBbYmFja2dyb3VuZEdyYWRpZW50XT1cImZhbHNlXCIgW2JhY2tncm91bmRTdHJva2VXaWR0aF09XCIzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcD1cIkluIHByb2dyZXNzXCIgW3Nob3daZXJvT3V0ZXJTdHJva2VdPWZhbHNlIFtiYWNrZ3JvdW5kUGFkZGluZ109XCItOVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdGFydEZyb21aZXJvXT1cImZhbHNlXCIgW2JhY2tncm91bmRQYWRkaW5nXT1cIjBcIiBbaW1hZ2VIZWlnaHRdPVwiMjJcIiBbaW1hZ2VXaWR0aF09XCIyMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93QmFja2dyb3VuZF09XCJmYWxzZVwiIFtvdXRlclN0cm9rZUxpbmVjYXBdPVwiJ2J1dHQnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9jaXJjbGUtcHJvZ3Jlc3M+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSA8d3Mtd2lkZ2V0LWNvbnRlbnQtcHJvZ3Jlc3MgKm5nSWY9XCJjb250ZW50Py5pZGVudGlmaWVyXCIgW2ZvclByZXZpZXddPVwiZm9yUHJldmlld1wiXG4gICAgICAgICAgICAgICAgICAgIFtjb250ZW50SWRdPVwiY29udGVudD8uaWRlbnRpZmllclwiIGNsYXNzPVwicHJvZ3Jlc3MtYmFyLXRoaW5cIiBbcHJvZ3Jlc3NdPVwiY29udGVudD8uY29tcGxldGlvblBlcmNlbnRhZ2VcIlxuICAgICAgICAgICAgICAgICAgICBbcHJvZ3Jlc3NUeXBlXT1cIidwZXJjZW50YWdlJ1wiPlxuICAgICAgICAgICAgICAgICAgPC93cy13aWRnZXQtY29udGVudC1wcm9ncmVzcz4gLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZWxzZUJsb2NrPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZS1wcm9ncmVzcyBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHByb2dyZXNzXCIgW3BlcmNlbnRdPVwiMFwiIFtyYWRpdXNdPVwiMTFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZVdpZHRoXT1cIjJcIiBbaW5uZXJTdHJva2VXaWR0aF09XCIyXCIgW291dGVyU3Ryb2tlQ29sb3JdPVwiJyM4MDgwODAnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaW5uZXJTdHJva2VDb2xvcl09XCInIzgwODA4MCdcIiBbYW5pbWF0aW9uXT1cInRydWVcIiBbc3BhY2VdPVwiLTJcIiBbc2hvd1VuaXRzXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYW5pbWF0aW9uRHVyYXRpb25dPVwiMjUwXCIgW3Nob3dUaXRsZV09XCJmYWxzZVwiIFtiYWNrZ3JvdW5kUGFkZGluZ109XCIwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYmFja2dyb3VuZFBhZGRpbmddPVwiLTlcIiBbb3V0ZXJTdHJva2VMaW5lY2FwXT1cIididXR0J1wiIG1hdFRvb2x0aXA9XCJOb3Qgc3RhcnRlZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dTdWJ0aXRsZV09XCJmYWxzZVwiIFtzaG93SW5uZXJTdHJva2VdPVwidHJ1ZVwiIFtjbG9ja3dpc2VdPVwidHJ1ZVwiIFtpbWFnZUhlaWdodF09XCIyMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2ltYWdlV2lkdGhdPVwiMjJcIiBbc2hvd0JhY2tncm91bmRdPVwiZmFsc2VcIj48L2NpcmNsZS1wcm9ncmVzcz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPHA+bm8gZGF0YTwvcD4gLS0+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwhLS0gZGVhY3RpdmF0ZWQgYXMgcGVyIE5JQyBDRU8gcmVxdWlyZW1lbnQgdG8gYWNjZXNzIGNvdXJzZSB3dGhvdXQgbG9naW4gLS0+XG4gICAgICAgICAgICA8IS0tIEZvciBsb2NrZWQgYXNzZXNzbWVudHM6IHNob3cgY29udGVudCBidXQgbWFrZSBpdCBub24tY2xpY2thYmxlIC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIndpZHRoLWV4cGFuZFwiICpuZ0lmPVwiaXNNaWxlc3RvbmVBc3Nlc3NtZW50TG9ja2VkICYmIGlzRW5yb2xsZWQ7IGVsc2UgY2xpY2thYmxlQ29udGVudFwiXG4gICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydtbC0zJzogaXNFbnJvbGxlZH1cIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC10cnVuY2F0ZSBvcGFjaXR5LTYwXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sIHNtOmZsZXgtcm93IGZsZXgtd3JhcFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIGdhcC0yIHctZnVsbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cInRleHQtZ3JheS01MDBcIj5sb2NrPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cIm1hcmdpbi1yZW1vdmUgdGV4dC10cnVuY2F0ZSBtYXQtYm9keS0yIGZsZXgtYXV0byBmb250LWJvbGQgbm9kdHJhbnNsYXRlIHRleHQtZ3JheS02MDBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWF0VG9vbHRpcF09XCIoY29udGVudD8ubmFtZSArIChjb250ZW50Py5jb250ZXh0Q2F0ZWdvcnkgJiYgKGNvbnRlbnQ/LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQpID8gJyAtICcgKyBjb250ZW50Py5jb250ZXh0Q2F0ZWdvcnkgOiAnJykpLmxlbmd0aCA+IDUwID8gKGNvbnRlbnQ/Lm5hbWUgKyAoY29udGVudD8uY29udGV4dENhdGVnb3J5ICYmIChjb250ZW50Py5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5GSU5BTF9BU1NFU1NNRU5UKSA/ICcgLSAnICsgY29udGVudD8uY29udGV4dENhdGVnb3J5IDogJycpKSA6ICcnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcFBvc2l0aW9uPVwiYWJvdmVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgKGNvbnRlbnQ/Lm5hbWUgKyAoY29udGVudD8uY29udGV4dENhdGVnb3J5ICYmIChjb250ZW50Py5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5GSU5BTF9BU1NFU1NNRU5UICk/ICcgLSAnICsgY29udGVudD8uY29udGV4dENhdGVnb3J5IDogJycpKSB8IHRydW5jYXRlOjUwIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNvbnRlbnQtdHlwZSBvcHRpb25hbC1zcGFuIG5vZHRyYW5zbGF0ZVwiICpuZ0lmPVwiY29udGVudD8ub3B0aW9uYWxSZWFkaW5nXCI+e3tcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAncGxheWVyYnJpZWYub3B0aW9uYWwnIHwgdHJhbnNsYXRlIHwgdGl0bGVjYXNlfX0gPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBmb3IgZGVmYXVsdCBncmV5IGljb25zIC0tPlxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIXBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKSB8fCAhaXNFbnJvbGxlZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlc2ljb25zIHdzLW1hdC1ibGFjazYwLXRleHRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L3ZpZGVvLnN2Z1wiIGFsdD1cIlZpZGVvXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICd2aWRlby9tcDQnIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAndmlkZW8veC15b3V0dWJlJyB8fFxuICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ/Lm1pbWVUeXBlID09PSdhcHBsaWNhdGlvbi94LW1wZWdVUkwnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9hdWRpby5zdmdcIiBhbHQ9XCJBdWRpb1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIiAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXVkaW8vbXBlZydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L3BkZi5zdmdcIiBhbHQ9XCJQREZcIiBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3BkZidcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2xpbmsuc3ZnXCIgYWx0PVwiSW50ZXJhY3RpdmVDb250ZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi92bmQuZWtzdGVwLmh0bWwtYXJjaGl2ZScgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICd0ZXh0L3gtdXJsJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvYXNzZXNzbWVudC5zdmdcIiBhbHQ9XCJBc3Nlc3NtZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9qc29uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3F1aXonIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLnN1bmJpcmQucXVlc3Rpb25zZXQnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9pbWFnZS5zdmdcIiBhbHQ9XCJJbWFnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnaW1hZ2UvcG5nJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2ltYWdlL2pwZWcnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9jb250ZW50X2NvcHkuc3ZnXCIgY2xhc3M9XCJjb250ZW50aWNvblwiIGFsdD1cIkNvdXJzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5la3N0ZXAuY29udGVudC1jb2xsZWN0aW9uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3N1cnZleSdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L21vZHVsZS5zdmdcIiBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWx0PVwib2ZmbGluZSBzZXNzaW9uc1wiICpuZ0lmPVwiY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL29mZmxpbmUnXCI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5GSU5BTF9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5DT01QX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlNUQU5EQUxPTkVfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuUFJBQ1RJQ0VfUkVTT1VSQ0VcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJyZXNvdXJjZUR1cmF0aW9uIHdzLW1hdC1ibGFjazYwLXRleHQgbm9kdHJhbnNsYXRlXCI+e3sgY29udGVudD8ubWF4UXVlc3Rpb25zXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9fSB7eyAncGxheWVyYnJpZWYucXVlc3Rpb25zJyB8IHRyYW5zbGF0ZSB8IHRpdGxlY2FzZX19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhKGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuQ09NUF9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5TVEFOREFMT05FX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInJlc291cmNlRHVyYXRpb24gd3MtbWF0LWJsYWNrNjAtdGV4dCBub2R0cmFuc2xhdGVcIj57eyAoY29udGVudD8uZHVyYXRpb258fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGllcmFyY2h5TWFwRGF0YVtjb250ZW50Py5pZGVudGlmaWVyXT8uZXhwZWN0ZWREdXJhdGlvbiB8fCAwKXxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpcGVEdXJhdGlvblRyYW5zZm9ybTpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdobXMnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICA8IS0tIExvY2sgbWVzc2FnZSBkaXNwbGF5ZWQgQkVMT1cgYXNzZXNzbWVudCBkZXRhaWxzIHdoZW4gbG9ja2VkIC0tPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb250ZW50LWxvY2tpbmcgZmxleCB3LWZ1bGwgZmxleC1taWRkbGUgbXQtMiBnYXAtMiBweC0yIHB5LTEgYmctb3JhbmdlLTUwIGJvcmRlci1sLTQgYm9yZGVyLW9yYW5nZS00MDBcIj5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwibG9jay1pY29uIHRleHQtb3JhbmdlLTYwMFwiIHN0eWxlPVwiZm9udC1zaXplOiAxOHB4OyB3aWR0aDogMThweDsgaGVpZ2h0OiAxOHB4O1wiPmxvY2s8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImxvY2stbWVzc2FnZSBtYXQtYm9keS0yIHRleHQtb3JhbmdlLTgwMFwiIHN0eWxlPVwiZm9udC1zaXplOiAxM3B4O1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgVGhpcyBjb250ZW50IGlzIGxvY2tlZC4gQ29tcGxldGUgYWxsIG1hbmRhdG9yeSBpdGVtcyB0byB1bmxvY2sgdGhlIGFzc2Vzc21lbnQuXG4gICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgXG4gICAgICAgICAgICA8IS0tIENsaWNrYWJsZSBjb250ZW50IHRlbXBsYXRlICh3aGVuIE5PVCBsb2NrZWQpIC0tPlxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNjbGlja2FibGVDb250ZW50PlxuICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwid2lkdGgtZXhwYW5kXCJcbiAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmRpc2FibGVkXT1cIihmb3JQcmV2aWV3IHx8ICFpc0VuYWJsZWQgfHwgIWlzRW5yb2xsZWQgfHwgIWlzQmF0Y2hJblByb2dlc3MgfHwgIWlzQ29udGVudFVubG9ja2VkIHx8IGlzUGFyZW50TWlsZXN0b25lTG9ja2VkKSA/IHRydWUgOiBudWxsXCJcbiAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydtbC0zJzogaXNFbnJvbGxlZH1cIlxuICAgICAgICAgICAgICAgICAgICBbcm91dGVyTGlua109XCIoaXNBbGxvd2VkICYmICFmb3JQcmV2aWV3ICYmIGlzRW5hYmxlZCAmJiAhaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQpID8gcmVzb3VyY2VMaW5rLnVybCA6IG51bGxcIlxuICAgICAgICAgICAgICAgICAgICBbcXVlcnlQYXJhbXNdPVwiKGlzQWxsb3dlZCAmJiAhZm9yUHJldmlldyAmJiBpc0VuYWJsZWQgJiYgIWlzUGFyZW50TWlsZXN0b25lTG9ja2VkKSAgPyByZXNvdXJjZUxpbmsucXVlcnlQYXJhbXMgOiBudWxsXCJcbiAgICAgICAgICAgICAgICAgICAgW21hdFRvb2x0aXBdPVwiaXNQYXJlbnRNaWxlc3RvbmVMb2NrZWQgPyAnVGhpcyBjb250ZW50IGlzIGxvY2tlZC4gQ29tcGxldGUgcHJldmlvdXMgbWlsZXN0b25lIHRvIHZpZXcgdGhpcyBjb250ZW50LicgOiAnJ1wiXG4gICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXBQb3NpdGlvbj1cImFib3ZlXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgW25nQ2xhc3NdPVwieydyZXNvdXJjZS1hY3RpdmUnOiBwYXRoU2V0Py5oYXMoY29udGVudD8uaWRlbnRpZmllcikgJiYgaXNFbnJvbGxlZH1cIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtdHJ1bmNhdGUgXCIgW25nQ2xhc3NdPVwieydjdXJzb3ItcG9pbnRlcic6ICFpc0VuYWJsZWQgJiYgaXNFbnJvbGxlZH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNvbnRlbnQudmlld0NoaWxkcmVuID0gIWNvbnRlbnQudmlld0NoaWxkcmVuOyByYWlzZVRlbGVtZXRyeSgpOyBjaGFuZ2VSZXNvdXJjZSgpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCBzbTpmbGV4LXJvdyBmbGV4LXdyYXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cIm1hcmdpbi1yZW1vdmUgdGV4dC10cnVuY2F0ZSBtYXQtYm9keS0yIGZsZXgtYXV0byBmb250LWJvbGQgbm9kdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieyd0ZXh0LWFjdGl2ZSc6IHBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKSAmJiBpc0Vucm9sbGVkfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttYXRUb29sdGlwXT1cIihjb250ZW50Py5uYW1lICsgKGNvbnRlbnQ/LmNvbnRleHRDYXRlZ29yeSAmJiAoY29udGVudD8ucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCkgPyAnIC0gJyArIGNvbnRlbnQ/LmNvbnRleHRDYXRlZ29yeSA6ICcnKSkubGVuZ3RoID4gNTAgPyAoY29udGVudD8ubmFtZSArIChjb250ZW50Py5jb250ZXh0Q2F0ZWdvcnkgJiYgKGNvbnRlbnQ/LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQpID8gJyAtICcgKyBjb250ZW50Py5jb250ZXh0Q2F0ZWdvcnkgOiAnJykpIDogJydcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRUb29sdGlwUG9zaXRpb249XCJhYm92ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyAoY29udGVudD8ubmFtZSArIChjb250ZW50Py5jb250ZXh0Q2F0ZWdvcnkgJiYgKGNvbnRlbnQ/LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQpPyAnIC0gJyArIGNvbnRlbnQ/LmNvbnRleHRDYXRlZ29yeSA6ICcnKSkgfCB0cnVuY2F0ZTo1MCB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNvbnRlbnQtdHlwZSBvcHRpb25hbC1zcGFuIG5vZHRyYW5zbGF0ZVwiICpuZ0lmPVwiY29udGVudD8ub3B0aW9uYWxSZWFkaW5nXCI+e3tcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3BsYXllcmJyaWVmLm9wdGlvbmFsJyB8IHRyYW5zbGF0ZSB8IHRpdGxlY2FzZX19IDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBmb3IgZGVmYXVsdCBncmV5IGljb25zIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFwYXRoU2V0Py5oYXMoY29udGVudD8uaWRlbnRpZmllcikgfHwgIWlzRW5yb2xsZWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVzaWNvbnMgd3MtbWF0LWJsYWNrNjAtdGV4dFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L3ZpZGVvLnN2Z1wiIGFsdD1cIlZpZGVvXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIiAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAndmlkZW8vbXA0JyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ3ZpZGVvL3gteW91dHViZScgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudD8ubWltZVR5cGUgPT09J2FwcGxpY2F0aW9uL3gtbXBlZ1VSTCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9hdWRpby5zdmdcIiBhbHQ9XCJBdWRpb1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCIgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2F1ZGlvL21wZWcnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvcGRmLnN2Z1wiIGFsdD1cIlBERlwiIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3BkZidcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9saW5rLnN2Z1wiIGFsdD1cIkludGVyYWN0aXZlQ29udGVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi92bmQuZWtzdGVwLmh0bWwtYXJjaGl2ZScgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICd0ZXh0L3gtdXJsJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2Fzc2Vzc21lbnQuc3ZnXCIgYWx0PVwiQXNzZXNzbWVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9qc29uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3F1aXonIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLnN1bmJpcmQucXVlc3Rpb25zZXQnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvaW1hZ2Uuc3ZnXCIgYWx0PVwiSW1hZ2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnaW1hZ2UvcG5nJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2ltYWdlL2pwZWcnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvY29udGVudF9jb3B5LnN2Z1wiIGNsYXNzPVwiY29udGVudGljb25cIiBhbHQ9XCJDb3Vyc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLmVrc3RlcC5jb250ZW50LWNvbGxlY3Rpb24nIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vc3VydmV5J1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L21vZHVsZS5zdmdcIiBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsdD1cIm9mZmxpbmUgc2Vzc2lvbnNcIiAqbmdJZj1cImNvbnRlbnQubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9vZmZsaW5lJ1wiPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5DT01QX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5TVEFOREFMT05FX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5QUkFDVElDRV9SRVNPVVJDRVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJyZXNvdXJjZUR1cmF0aW9uIHdzLW1hdC1ibGFjazYwLXRleHQgbm9kdHJhbnNsYXRlXCI+e3sgY29udGVudD8ubWF4UXVlc3Rpb25zXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfX0ge3sgJ3BsYXllcmJyaWVmLnF1ZXN0aW9ucycgfCB0cmFuc2xhdGUgfCB0aXRsZWNhc2V9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhKGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkNPTVBfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlNUQU5EQUxPTkVfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJyZXNvdXJjZUR1cmF0aW9uIHdzLW1hdC1ibGFjazYwLXRleHQgbm9kdHJhbnNsYXRlXCI+e3sgKGNvbnRlbnQ/LmR1cmF0aW9ufHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWVyYXJjaHlNYXBEYXRhW2NvbnRlbnQ/LmlkZW50aWZpZXJdPy5leHBlY3RlZER1cmF0aW9uIHx8IDApfFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpcGVEdXJhdGlvblRyYW5zZm9ybTpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnaG1zJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gZm9yIHdoaXRlIGljb25zIHdoZW4gY29udGVudCBoaWdobGlnaHRlZCAtLT5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKSAmJiBpc0Vucm9sbGVkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVzaWNvbnMgd3MtbWF0LXdoaXRlLXRleHRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS92aWRlby5zdmdcIiBhbHQ9XCJWaWRlb1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIiAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAndmlkZW8vbXA0JyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ3ZpZGVvL3gteW91dHViZScgfHxcbiAgICAgICAgICAgICAgICAgICAgICBjb250ZW50Py5taW1lVHlwZSA9PT0nYXBwbGljYXRpb24veC1tcGVnVVJMJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L3doaXRlL2F1ZGlvLnN2Z1wiIGFsdD1cIkF1ZGlvXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhdWRpby9tcGVnJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L3doaXRlL3BkZi5zdmdcIiBhbHQ9XCJQREZcIiBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3BkZidcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9saW5rLnN2Z1wiIGFsdD1cIkludGVyYWN0aXZlQ29udGVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLmVrc3RlcC5odG1sLWFyY2hpdmUnIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAndGV4dC94LXVybCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9hc3Nlc3NtZW50LnN2Z1wiIGFsdD1cIkFzc2Vzc21lbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL2pzb24nIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vcXVpeicgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi92bmQuc3VuYmlyZC5xdWVzdGlvbnNldCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2ltYWdlLnN2Z1wiIGFsdD1cIkltYWdlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdpbWFnZS9wbmcnIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnaW1hZ2UvanBlZydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9jb250ZW50X2NvcHkuc3ZnXCIgY2xhc3M9XCJjb250ZW50aWNvblwiIGFsdD1cIkNvdXJzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudC5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5la3N0ZXAuY29udGVudC1jb2xsZWN0aW9uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3N1cnZleSdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9tb2R1bGUuc3ZnXCIgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsdD1cIm9mZmxpbmUgc2Vzc2lvbnNcIiAqbmdJZj1cImNvbnRlbnQubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9vZmZsaW5lJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkNPTVBfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuU1RBTkRBTE9ORV9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5QUkFDVElDRV9SRVNPVVJDRVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInJlc291cmNlRHVyYXRpb24gd3MtbWF0LWJsYWNrNjAtdGV4dCBub2R0cmFuc2xhdGVcIj57eyBjb250ZW50Py5tYXhRdWVzdGlvbnNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH19IHt7ICdwbGF5ZXJicmllZi5xdWVzdGlvbnMnIHwgdHJhbnNsYXRlIHwgdGl0bGVjYXNlfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiEoY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5GSU5BTF9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5DT01QX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlNUQU5EQUxPTkVfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuUFJBQ1RJQ0VfUkVTT1VSQ0UpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicmVzb3VyY2VEdXJhdGlvbiB3cy1tYXQtYmxhY2s2MC10ZXh0IG5vZHRyYW5zbGF0ZVwiPnt7IChjb250ZW50Py5kdXJhdGlvbnx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWVyYXJjaHlNYXBEYXRhW2NvbnRlbnQ/LmlkZW50aWZpZXJdPy5leHBlY3RlZER1cmF0aW9uIHx8IDApfFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGlwZUR1cmF0aW9uVHJhbnNmb3JtOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2htcydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudD8ucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCAmJiBjaGVja0ZvckN1cmF0ZWRQcm9ncmFtICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBpc0NvbnRlbnRVbmxvY2tlZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbnRlbnQtbG9ja2luZyBmbGV4IHctZnVsbCBmbGV4LW1pZGRsZSBtYi0yIGdhcC0zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwidW5sb2NrLWljb25cIj5sb2NrX29wZW5fcmlnaHQ8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidW5sb2NrLW1lc3NhZ2UgbWF0LWJvZHktMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzIGNvbnRlbnQgaXMgdW5sb2NrZWQuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICA8IS0tIERvd25sb2FkIGJ1dHRvbiBmb3IgcGRmIHJlc291cmNlcyAtLT5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInNob3VsZFNob3dEb3dubG9hZEJ1dHRvbihjb250ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRvd25sb2FkLWJ0biBtYXQtYm9keS0yIG10LTIgc206bXQtMVwiIChjbGljayk9XCJkb3dubG9hZENvbnRlbnQoY29udGVudCwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydhY3RpdmUnOiBwYXRoU2V0Py5oYXMoY29udGVudD8uaWRlbnRpZmllcil9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJkb3dubG9hZC1saW5rIGZsZXggaXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiXCI+RG93bmxvYWQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG48L25nLWNvbnRhaW5lcj5cblxuPG1hdC1tZW51ICNidXR0b25NZW51PVwibWF0TWVudVwiPlxuICAgIDxhIG1hdC1tZW51LWl0ZW0gW3JvdXRlckxpbmtdPVwiJy4uLycgKyBjb250ZW50Py5pZGVudGlmaWVyICsgJy9vdmVydmlldydcIiBbcXVlcnlQYXJhbXNdPVwiY29udGV4dFBhdGhcIlxuICAgICAgICBjbGFzcz1cImZsZXggZmxleC1taWRkbGVcIj5cbiAgICAgICAgPG1hdC1pY29uPnRvYzwvbWF0LWljb24+XG4gICAgICAgIDxoMyBjbGFzcz1cIm1hcmdpbi1yZW1vdmUgbm9kdHJhbnNsYXRlXCI+XG4gICAgICAgICAgICBWaWV3IERldGFpbHNcbiAgICAgICAgPC9oMz5cbiAgICA8L2E+XG48L21hdC1tZW51PlxuXG48bmctdGVtcGxhdGUgI2NvbGxlY3Rpb25UZW1wbGF0ZT5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNDb2xsZWN0aW9uXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb2xsZWN0aW9uLXdyYXBwZXIgcC00IGZsZXggZmxleC1jb2wgcG9zaXRpb24tcmVsYXRpdmVcIiBbbmdDbGFzc109XCJ7J29wZW4nOiBjaGVjayhjb250ZW50KSxcbiAgICAgICAgICAgICdjbG9zZSc6ICFjb250ZW50LnZpZXdDaGlsZHJlbixcbiAgICAgICAgICAgICdjb3Vyc2UnOiFpc01vZHVsZSwgJ21vZHVsZSc6IGlzTW9kdWxlLFxuICAgICAgICAgICAgJ2NvbnRlbnQtYWN0aXZlJzogcGF0aFNldD8uaGFzKGNvbnRlbnQuaWRlbnRpZmllcikgJiYgaXNFbnJvbGxlZH1cIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYXJkLWNvbGxlY3Rpb24gdy1hdXRvIHNtOnctMTAwIHBhZGRpbmctcmlnaHQteGxcIj5cbiAgICAgICAgICAgICAgICA8IS0tIDxpbWcgY2xhc3M9XCJjYXJkLXRodW1ibmFpbCB3cy1tYXQtcHJpbWFyeS1saXRlLWJhY2tncm91bmRcIiBbc3JjXT1cImNvbnRlbnQ/LmFwcEljb25cIiBhbHQ9XCJUaHVtYm5haWxcIlxuICAgICAgICAgICAgKGNsaWNrKT1cImNvbnRlbnQudmlld0NoaWxkcmVuID0gIWNvbnRlbnQudmlld0NoaWxkcmVuXCIgW3dzVXRpbHNEZWZhdWx0VGh1bWJuYWlsXT1cImRlZmF1bHRUaHVtYm5haWxcIiAvPiAtLT5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCBmbGV4LXdyYXAgZmxleC1iZXR3ZWVuIHdpZHRoLWV4cGFuZCBwci0wIHctMTAwIFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC10cnVuY2F0ZVwiIFtuZ0NsYXNzXT1cInsnY3Vyc29yLXBvaW50ZXInOiAhaXNFbmFibGVkfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiY29udGVudC52aWV3Q2hpbGRyZW4gPSAhY29udGVudC52aWV3Q2hpbGRyZW5cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciBtYi0xIHNtOmZsZXgtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImlzTW9kdWxlICYmIGlzRW5yb2xsZWQgJiYgIWlzTWlsZXN0b25lTG9ja2VkICYmICFpc1BhcmVudE1pbGVzdG9uZUxvY2tlZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIiFmb3JQcmV2aWV3ICYmIGNvbnRlbnQ/LmlkZW50aWZpZXIgJiYgZ2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcikgOyBlbHNlIGVsc2VCbG9ja1wiPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0Q29tcGxldGlvblN0YXR1cyhjb250ZW50LmlkZW50aWZpZXIpID09IDJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29tcGxldGVkIG1yLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cImNvbXBsZXRlZC1pY29uXCIgW2NvbG9yXT1cImJsdWVcIj5jaGVja19jaXJjbGU8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldENvbXBsZXRpb25TdGF0dXMoY29udGVudD8uaWRlbnRpZmllcikgPCAyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZS1wcm9ncmVzcyBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHByb2dyZXNzIG1yLTFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGVyY2VudF09XCJnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKVwiIFtyYWRpdXNdPVwiMTBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3V0ZXJTdHJva2VXaWR0aF09XCIyXCIgW2lubmVyU3Ryb2tlV2lkdGhdPVwiMlwiIFtzcGFjZV09XCItMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZUNvbG9yXT1cInByb2dyZXNzQ29sb3IyKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaW5uZXJTdHJva2VDb2xvcl09XCIncmdiYSgwLCAwLCAwLCAwLjE2KSdcIiBbYW5pbWF0aW9uXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYW5pbWF0aW9uRHVyYXRpb25dPVwiMjUwXCIgW3Nob3dUaXRsZV09XCJmYWxzZVwiIFtzaG93VW5pdHNdPVwiZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2hvd1N1YnRpdGxlXT1cImZhbHNlXCIgW3Nob3dJbm5lclN0cm9rZV09XCJ0cnVlXCIgW2Nsb2Nrd2lzZV09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2JhY2tncm91bmRPcGFjaXR5XT1cIjBcIiBbYmFja2dyb3VuZEdyYWRpZW50XT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2JhY2tncm91bmRTdHJva2VXaWR0aF09XCIzXCIgbWF0VG9vbHRpcD1cIkluIHByb2dyZXNzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3daZXJvT3V0ZXJTdHJva2VdPWZhbHNlIFtiYWNrZ3JvdW5kUGFkZGluZ109XCItN1wiIFtzdGFydEZyb21aZXJvXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2JhY2tncm91bmRQYWRkaW5nXT1cIjBcIiBbaW1hZ2VIZWlnaHRdPVwiMThcIiBbaW1hZ2VXaWR0aF09XCIxOFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93QmFja2dyb3VuZF09XCJmYWxzZVwiIFtvdXRlclN0cm9rZUxpbmVjYXBdPVwiJ2J1dHQnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9jaXJjbGUtcHJvZ3Jlc3M+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZWxzZUJsb2NrPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZS1wcm9ncmVzcyBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHByb2dyZXNzIG1yLTFcIiBbcGVyY2VudF09XCIwXCIgW3JhZGl1c109XCIxMVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlV2lkdGhdPVwiMlwiIFtpbm5lclN0cm9rZVdpZHRoXT1cIjJcIiBbb3V0ZXJTdHJva2VDb2xvcl09XCInIzgwODA4MCdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpbm5lclN0cm9rZUNvbG9yXT1cIicjODA4MDgwJ1wiIFthbmltYXRpb25dPVwidHJ1ZVwiIFtzcGFjZV09XCItMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dVbml0c109XCJmYWxzZVwiIFthbmltYXRpb25EdXJhdGlvbl09XCIyNTBcIiBbc2hvd1RpdGxlXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYmFja2dyb3VuZFBhZGRpbmddPVwiMFwiIFtiYWNrZ3JvdW5kUGFkZGluZ109XCItOVwiIFtvdXRlclN0cm9rZUxpbmVjYXBdPVwiJ2J1dHQnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRUb29sdGlwPVwiTm90IHN0YXJ0ZWRcIiBbc2hvd1N1YnRpdGxlXT1cImZhbHNlXCIgW3Nob3dJbm5lclN0cm9rZV09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xvY2t3aXNlXT1cInRydWVcIiBbaW1hZ2VIZWlnaHRdPVwiMjJcIiBbaW1hZ2VXaWR0aF09XCIyMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dCYWNrZ3JvdW5kXT1cImZhbHNlXCI+PC9jaXJjbGUtcHJvZ3Jlc3M+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J2NvbGxlY3Rpb24tYWN0aXZlLWNsYXNzJzogcGF0aFNldD8uaGFzKGNvbnRlbnQ/LmlkZW50aWZpZXIpICYmIGlzRW5yb2xsZWR9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyAqbmdJZj1cImlzTWlsZXN0b25lTG9ja2VkXCIgc3JjPVwiYXNzZXRzL2ljb25zL2h1YnMvbG9jay5zdmdcIiBhbHQ9XCJMb2NrZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImxvY2staWNvbiBtci0yIG1hcmdpbi1ib3R0b20teHhzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXgtYXV0byBmbGV4IGZsZXgtY29sXCIgc3R5bGU9XCJtaW4td2lkdGg6IDA7XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwibWFyZ2luLXJlbW92ZSB0ZXh0LXRydW5jYXRlIG1hdC1zdWJoZWFkaW5nLTEgZm9udC1ib2xkIG5vZHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J3RleHQtYWN0aXZlJzogcGF0aFNldD8uaGFzKGNvbnRlbnQuaWRlbnRpZmllcikgJiYgaXNFbnJvbGxlZH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21hdFRvb2x0aXBdPVwiY29udGVudD8ubmFtZT8ubGVuZ3RoID4gNTAgPyBjb250ZW50Py5uYW1lIDogJydcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcFBvc2l0aW9uPVwiYWJvdmVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPnt7aXNNaWxlc3RvbmUgPyBpbmRleCAtMSA6IGluZGV4fX0uIDwvc3Bhbj57eyBjb250ZW50Py5uYW1lIHwgdHJ1bmNhdGU6NTAgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtMVwiICpuZ0lmPVwiaXNNaWxlc3RvbmUgJiYgaXNNaWxlc3RvbmVMb2NrZWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibG9ja2VkLXRleHRcIj5Mb2NrZWQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtMVwiICpuZ0lmPVwiY29udGVudD8uaXNNYW5kYXRvcnlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWFuZGF0b3J5LXRleHQgbWF0LWNhcHRpb25cIj5NYW5kYXRvcnk8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0eXBlLWNvbnRhaW5lciByZXNvdXJjZSBtdC0yIHNtOm10LTBcIiAqbmdJZj1cImNvbnRlbnQ/LmNhdGVnb3J5ID09PSAnUmVzb3VyY2UnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm1yLTEgY3VzdG9tLWljb24gcm90YXRlLTkwXCI+Y2FsbF90b19hY3Rpb248L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5vZHRyYW5zbGF0ZVwiPlJlc291cmNlPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0eXBlLWNvbnRhaW5lciBtb2R1bGUgbXQtMiBzbTptdC0wXCIgKm5nSWY9XCJjb250ZW50Py5jYXRlZ29yeSA9PT0gJ0NvbGxlY3Rpb24nXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm1yLTEgY3VzdG9tLWljb24gcm90YXRlLTkwXCI+Y2FsbF90b19hY3Rpb248L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5vZHRyYW5zbGF0ZVwiPk1vZHVsZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidHlwZS1jb250YWluZXIgY291cnNlIG10LTIgc206bXQtMFwiICpuZ0lmPVwiY29udGVudD8uY2F0ZWdvcnkgPT09ICdDb3Vyc2UnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm1yLTEgY3VzdG9tLWljb24gcm90YXRlLTkwXCI+Y2FsbF90b19hY3Rpb248L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5vZHRyYW5zbGF0ZVwiPkNvdXJzZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBNaWxlc3RvbmUgQmFkZ2UgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaXNNaWxlc3RvbmVcIiBjbGFzcz1cIm1pbGVzdG9uZS1iYWRnZSBtdC0yIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1pbGVzdG9uZS1iYWRnZS10ZXh0IG5vZHRyYW5zbGF0ZVwiPk1pbGVzdG9uZSB7e2luZGV4IC0gMX19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIE1pbGVzdG9uZSBEZXNjcmlwdGlvbiAoMiBsaW5lcyB3aXRoIGVsbGlwc2lzKSAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxwICNtaWxlc3RvbmVEZXNjUmVmICpuZ0lmPVwiaXNNaWxlc3RvbmUgJiYgY29udGVudD8uZGVzY3JpcHRpb25cIiBjbGFzcz1cIm1pbGVzdG9uZS1kZXNjcmlwdGlvbiBtdC0yIG5vZHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW21hdFRvb2x0aXBdPVwiaXNNdWx0aUxpbmVUcnVuY2F0ZWQobWlsZXN0b25lRGVzY1JlZikgPyBjb250ZW50Py5kZXNjcmlwdGlvbiA6ICcnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRUb29sdGlwUG9zaXRpb249XCJhYm92ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0VG9vbHRpcENsYXNzPVwibXVsdGlsaW5lLXRvb2x0aXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBjb250ZW50Py5kZXNjcmlwdGlvbiB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1yb3cgZ2FwLTMgaXRlbXMtY2VudGVyIGNvbnRlbnQta2V5LXZhbHVlcyBtdC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwiIWlzTW9kdWxlXCIgYWx0PVwiY291cnNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0aW1lLWljb24gaWNvbi1jb2xvclwiPnZpZGVvX2xpYnJhcnk8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgKm5nSWY9XCJpc01vZHVsZVwiIGFsdD1cIk1vZHVsZVwiIGNsYXNzPVwidGltZS1pY29uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvbW9kdWxlLnN2Z1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXhzIG5vZHRyYW5zbGF0ZVwiPnt7IChoaWVyYXJjaHlNYXBEYXRhW2NvbnRlbnQ/LmlkZW50aWZpZXJdPy5kdXJhdGlvbiB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxMjApfFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXBlRHVyYXRpb25UcmFuc2Zvcm06ICdobXMnIH19PC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudD8ubW9kdWxlQ291bnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInBlcmlvZFwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXhzIG5vZHRyYW5zbGF0ZVwiPnt7Y29udGVudD8ubW9kdWxlQ291bnR9fSB7e2NvbnRlbnQ/Lm1vZHVsZUNvdW50ID4gMT9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdtb2R1bGVzJyA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbW9kdWxlJ319PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnQ/LmxlYWZOb2Rlc0NvdW50XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJwZXJpb2RcIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC14cyBub2R0cmFuc2xhdGVcIj57e2NvbnRlbnQ/LmxlYWZOb2Rlc0NvdW50fX0ge3tjb250ZW50Py5sZWFmTm9kZXNDb3VudFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPjEgPyAnaXRlbXMnOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2l0ZW0nfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBNaWxlc3RvbmUgQ29tcGxldGlvbiBQcm9ncmVzcyAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJpc01pbGVzdG9uZSAmJiBpc0Vucm9sbGVkICYmICFpc01pbGVzdG9uZUxvY2tlZFwiIGNsYXNzPVwibWlsZXN0b25lLXByb2dyZXNzIG10LTIgZmxleCBmbGV4LWNvbCBnYXAtMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LXN0YXJ0IGdhcC00IHctMTAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWlsZXN0b25lLXByb2dyZXNzLXRleHQgbm9kdHJhbnNsYXRlXCI+e3tnZXRNaWxlc3RvbmVDb21wbGV0ZWRDb3VudCgpfX0gb2Yge3tjb250ZW50Py5sZWFmTm9kZXNDb3VudCB8fCAwfX0gY29tcGxldGVkPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFZpZXcgQWNoaWV2ZW1lbnQgQnV0dG9uIC0gU2hvd24gb25seSB3aGVuIGFsbCBtYW5kYXRvcnkgY29udGVudCBBTkQgbWlsZXN0b25lIGFzc2Vzc21lbnQgYXJlIGNvbXBsZXRlZCAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzTWlsZXN0b25lQ29tcGxldGUoY29udGVudD8uaWRlbnRpZmllcilcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwidmlldy1hY2hpZXZlbWVudC1idG4gbWwtNFwiIFtkaXNhYmxlZF09XCJhY2hpZXZlbWVudExvYWRpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJ2aWV3TWlsZXN0b25lQWNoaWV2ZW1lbnQoJGV2ZW50LCBjb250ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiIWFjaGlldmVtZW50TG9hZGluZ1wiPlZpZXcgQWNoaWV2ZW1lbnQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zcGlubmVyICpuZ0lmPVwiYWNoaWV2ZW1lbnRMb2FkaW5nXCIgW2RpYW1ldGVyXT1cIjE2XCIgW3N0cm9rZVdpZHRoXT1cIjJcIiBjb2xvcj1cInByaW1hcnlcIiBjbGFzcz1cImlubGluZS1zcGlubmVyXCI+PC9tYXQtc3Bpbm5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBVbmxvY2sgQ3JpdGVyaWEgTWVzc2FnZSBmb3IgTG9ja2VkIE1pbGVzdG9uZXMgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaXNNaWxlc3RvbmUgJiYgaXNFbnJvbGxlZCAmJiBpc01pbGVzdG9uZUxvY2tlZFwiIGNsYXNzPVwibWlsZXN0b25lLWxvY2tlZC1tZXNzYWdlIG10LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImxvY2tlZC1jcml0ZXJpYS10ZXh0IG1hdC1jYXB0aW9uXCIgc3R5bGU9XCJ3aGl0ZS1zcGFjZTogbm9ybWFsOyB3b3JkLXdyYXA6IGJyZWFrLXdvcmQ7IGRpc3BsYXk6IGlubGluZS1ibG9jazsgbWF4LXdpZHRoOiAxMDAlO1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBnZXRNaWxlc3RvbmVVbmxvY2tNZXNzYWdlKCkgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBGb3IgY291cnNlIHByb2dyZXNzIHRvIGJlIHNob3duIC0tPlxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNFbnJvbGxlZCAmJiAhaXNNaWxlc3RvbmVMb2NrZWQgJiYgIWlzUGFyZW50TWlsZXN0b25lTG9ja2VkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCIhZm9yUHJldmlldyAmJiBjb250ZW50Py5pZGVudGlmaWVyICYmIGdldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpICYmIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSAnQ291cnNlJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRDb21wbGV0aW9uU3RhdHVzKGNvbnRlbnQ/LmlkZW50aWZpZXIpID09IDJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtMiBtci00ICBmbGV4IGZsZXgtMSBmbGV4LWNvbCAgcHJvZ3Jlc3MtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1yb3cganVzdGlmeS1lbmQgdy1mdWxsIFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1hdC1ib2R5LTIgbm9kdHJhbnNsYXRlIFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKX19JTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx3cy13aWRnZXQtY29udGVudC1wcm9ncmVzcyBbY29udGVudElkXT1cImNvbnRlbnQ/LnByb2dyZXNzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Byb2dyZXNzXT1cImdldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Byb2dyZXNzVHlwZV09XCIncGVyY2VudGFnZSdcIiBbY3VzdG9tQ2xhc3NOYW1lXT1cIid2aWV3ZXItcHJvZ3Jlc3MnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC93cy13aWRnZXQtY29udGVudC1wcm9ncmVzcz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnQ/Lmlzc3VlZENlcnRpZmljYXRlc0lkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJtbC01IGNlcnRpZmljYXRlLWJ0blwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnZGlzYWJsZS1idG4nOiBkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZyB8fCBjb250ZW50Py5pc3N1ZWRDZXJ0aWZpY2F0ZXNJZH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiIWRvd25sb2FkQ2VydGlmaWNhdGVMb2FkaW5nICYmIGRvd25sb2FkQ2VydGlmaWNhdGUoY29udGVudD8uaXNzdWVkQ2VydGlmaWNhdGVzSWQpOyRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIDxpbWcgc3JjPVwiZnVzaW9uLWFzc2V0cy9pbWFnZXMvY2VydGlmaWNhdGUtaWNvLnN2Z1wiIHdpZHRoPVwiMjRcIiBoZWlnaHQ9XCIyNFwiPiAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJub2R0cmFuc2xhdGVcIj5DZXJ0aWZpY2F0ZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwiIWRvd25sb2FkQ2VydGlmaWNhdGVMb2FkaW5nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwibWwtMlwiPmFycm93X2Rvd253YXJkPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNlbnRlciBmbGV4IGZsZXgtbWlkZGxlIGNlcnRpZmljYXRlLWxvYWRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImRvd25sb2FkQ2VydGlmaWNhdGVMb2FkaW5nXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNwaW5uZXIgc3Ryb2tlV2lkdGg9XCIyXCIgc3Ryb2tlPVwiJ3doaXRlJ1wiIGNsYXNzPVwid2hpdGUtc3Bpbm5lclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2RpYW1ldGVyXT1cIjE2XCI+PC9tYXQtc3Bpbm5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIDxjaXJjbGUtcHJvZ3Jlc3MgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBwcm9ncmVzc1wiIFtwZXJjZW50XT1cIjEwMFwiIFtyYWRpdXNdPVwiMTJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlV2lkdGhdPVwiM1wiIFtpbm5lclN0cm9rZVdpZHRoXT1cIjNcIiBbc3BhY2VdPVwiLTNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlQ29sb3JdPVwicHJvZ3Jlc3NDb2xvcigpXCIgW2lubmVyU3Ryb2tlQ29sb3JdPVwiJ3JnYmEoMCwwLDAsLjE2KSdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2FuaW1hdGlvbl09XCJ0cnVlXCIgW2FuaW1hdGlvbkR1cmF0aW9uXT1cIjMwMFwiIFtzaG93VGl0bGVdPVwiZmFsc2VcIiBbc2hvd1VuaXRzXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93U3VidGl0bGVdPVwiZmFsc2VcIiBbc2hvd0lubmVyU3Ryb2tlXT1cInRydWVcIiBbY2xvY2t3aXNlXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2JhY2tncm91bmRPcGFjaXR5XT1cIjBcIiBbYmFja2dyb3VuZEdyYWRpZW50XT1cImZhbHNlXCIgW2JhY2tncm91bmRTdHJva2VXaWR0aF09XCIzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93WmVyb091dGVyU3Ryb2tlXT1mYWxzZSBbYmFja2dyb3VuZFBhZGRpbmddPVwiLTlcIiBbc3RhcnRGcm9tWmVyb109XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYmFja2dyb3VuZFBhZGRpbmddPVwiMFwiIFtpbWFnZUhlaWdodF09XCIyNFwiIFtpbWFnZVdpZHRoXT1cIjI0XCIgW3Nob3dCYWNrZ3JvdW5kXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZUxpbmVjYXBdPVwiJ2J1dHQnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvY2lyY2xlLXByb2dyZXNzPiAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0Q29tcGxldGlvblN0YXR1cyhjb250ZW50Py5pZGVudGlmaWVyKSA8IDJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtMiBtci00ICBmbGV4IGZsZXgtMSBmbGV4LWNvbCAgcHJvZ3Jlc3MtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1yb3cganVzdGlmeS1lbmQgdy1mdWxsIHdzLW1hdC1ibGFjay10ZXh0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWF0LWJvZHktMiAgd3MtbWF0LWJsYWNrLXRleHQgbm9kdHJhbnNsYXRlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2dldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpfX0lPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHdzLXdpZGdldC1jb250ZW50LXByb2dyZXNzIFtjb250ZW50SWRdPVwiY29udGVudD8ucHJvZ3Jlc3NcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcHJvZ3Jlc3NdPVwiZ2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcilcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcHJvZ3Jlc3NUeXBlXT1cIidwZXJjZW50YWdlJ1wiIFtjdXN0b21DbGFzc05hbWVdPVwiJ3ZpZXdlci1wcm9ncmVzcydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3dzLXdpZGdldC1jb250ZW50LXByb2dyZXNzPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudD8uaXNzdWVkQ2VydGlmaWNhdGVzSWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YSBjbGFzcz1cIm1sLTUgY2VydGlmaWNhdGUtYnRuXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydkaXNhYmxlLWJ0bic6IGRvd25sb2FkQ2VydGlmaWNhdGVMb2FkaW5nIHx8IGNvbnRlbnQ/Lmlzc3VlZENlcnRpZmljYXRlc0lkfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCIhZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmcgJiYgZG93bmxvYWRDZXJ0aWZpY2F0ZShjb250ZW50Py5pc3N1ZWRDZXJ0aWZpY2F0ZXNJZCk7JGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPGltZyBzcmM9XCJmdXNpb24tYXNzZXRzL2ltYWdlcy9jZXJ0aWZpY2F0ZS1pY28uc3ZnXCIgd2lkdGg9XCIyNFwiIGhlaWdodD1cIjI0XCI+IC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5vZHRyYW5zbGF0ZVwiPkNlcnRpZmljYXRlPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCIhZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJtbC0yXCI+YXJyb3dfZG93bndhcmQ8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2VudGVyIGZsZXggZmxleC1taWRkbGUgY2VydGlmaWNhdGUtbG9hZGVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtc3Bpbm5lciBzdHJva2VXaWR0aD1cIjJcIiBzdHJva2U9XCInd2hpdGUnXCIgY2xhc3M9XCJ3aGl0ZS1zcGlubmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGlhbWV0ZXJdPVwiMTZcIj48L21hdC1zcGlubmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlZS1hbGwtY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YSBocmVmPVwiamF2YXNjcmlwdDp2b2lkKDApXCIgcm9sZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNvbnRlbnQudmlld0NoaWxkcmVuID0gIWNvbnRlbnQudmlld0NoaWxkcmVuOyBleHBhbmRBY3RpdmUgPSBmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJzZWUtYWxsLWJ0biB0YWIgY3VzdG9tLWNoZXZyb24gY3VzdG9taWNvblwiIG1hdC1idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwiIWNvbnRlbnQudmlld0NoaWxkcmVuICYmICFpc01vZHVsZVwiPmtleWJvYXJkX2Fycm93X2Rvd248L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cImNvbnRlbnQudmlld0NoaWxkcmVuICYmICFpc01vZHVsZVwiPmtleWJvYXJkX2Fycm93X3VwPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCIhY29udGVudC52aWV3Q2hpbGRyZW4gJiYgaXNNb2R1bGVcIj5hZGQ8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cImNvbnRlbnQudmlld0NoaWxkcmVuICYmIGlzTW9kdWxlXCI+cmVtb3ZlPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjaGlsZC13cmFwcGVyICBcIiAqbmdJZj1cImNvbnRlbnQudmlld0NoaWxkcmVuXCIgW25nQ2xhc3NdPVwieydvcGVuJzogY29udGVudC52aWV3Q2hpbGRyZW4sXG4gICAgICAgICAgICAnY2xvc2UnOiAhY29udGVudC52aWV3Q2hpbGRyZW4sXG4gICAgICAgICAgICAnY291cnNlJzohaXNNb2R1bGUsXG4gICAgICAgICAgICAnbW9kdWxlJzogaXNNb2R1bGV9XCIgW0BwYW5lbEluT3V0XT5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjaGlsZHJlbi1jb250YWluZXJcIiBbbmdDbGFzc109XCJ7J21vZHVsZSc6IGlzTW9kdWxlLCAnJzogIWlzTW9kdWxlfVwiPlxuICAgICAgICAgICAgICAgIDx3cy13aWRnZXQtYXBwLXRvYy1jb250ZW50LWNhcmQtdjIgW2ZvclByZXZpZXddPVwiZm9yUHJldmlld1wiIFtjb21wb25lbnROYW1lXT1cImNvbXBvbmVudE5hbWVcIlxuICAgICAgICAgICAgICAgICAgICBbY29udGVudF09XCJjaGlsZFwiIFtleHBhbmRBbGxdPVwiZXhwYW5kQWxsXCIgW3Jvb3RJZF09XCJyb290SWRcIiBbYmF0Y2hJZF09XCJiYXRjaElkXCJcbiAgICAgICAgICAgICAgICAgICAgW3Jvb3RDb250ZW50VHlwZV09XCJyb290Q29udGVudFR5cGVcIiBbaW5kZXhdPVwiaisxXCIgW2Jhc2VDb250ZW50UmVhZERhdGFdPVwiYmFzZUNvbnRlbnRSZWFkRGF0YVwiXG4gICAgICAgICAgICAgICAgICAgIFtwYXRoU2V0XT1cInBhdGhTZXRcIiBbaGllcmFyY2h5TWFwRGF0YV09XCJoaWVyYXJjaHlNYXBEYXRhXCIgW2JhdGNoRGF0YV09XCJiYXRjaERhdGFcIlxuICAgICAgICAgICAgICAgICAgICBbbWxDb3Vyc2VdPVwibWxDb3Vyc2VcIiBbcGFyZW50TWlsZXN0b25lTG9ja2VkXT1cImlzTWlsZXN0b25lTG9ja2VkIHx8IGlzUGFyZW50TWlsZXN0b25lTG9ja2VkXCJcbiAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGNoaWxkIG9mIGNvbnRlbnQ/LmNoaWxkcmVuOyB0cmFja0J5OiBjb250ZW50VHJhY2tCeTsgbGV0IGo9IGluZGV4O2xldCBpc0ZpcnN0ID0gZmlyc3RcIlxuICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J21vZHVsZUNhcmQnOiBjaGVja0lzTW9kdWxlKGNoaWxkKSwgJ3Jlc291cmNlQ2FyZCc6ICFjaGVja0lzTW9kdWxlKGNoaWxkKSwgJ2ZpcnN0JzogaXNGaXJzdH1cIj5cbiAgICAgICAgICAgICAgICA8L3dzLXdpZGdldC1hcHAtdG9jLWNvbnRlbnQtY2FyZC12Mj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbjwvbmctdGVtcGxhdGU+XG5cblxuPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzUHJlQXNzZXNzbWVudFwiPlxuICAgIDxkaXYgY2xhc3M9XCJjb2xsZWN0aW9uLXdyYXBwZXIgcC00IGZsZXggZmxleC1jb2wgcG9zaXRpb24tcmVsYXRpdmVcIiBbbmdDbGFzc109XCJ7J29wZW4nOiBjaGVjayhjb250ZW50KSxcbiAgICAgICAgJ2NvdXJzZSc6IWlzTW9kdWxlLCAnbW9kdWxlJzogaXNNb2R1bGUsXG4gICAgICAgICdjb250ZW50LWFjdGl2ZSc6IHBhdGhTZXQ/Lmhhcyhjb250ZW50LmlkZW50aWZpZXIpfVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY2FyZC1jb2xsZWN0aW9uIHctYXV0byBzbTp3LTEwMCBwYWRkaW5nLXJpZ2h0LXhsXCI+XG4gICAgICAgICAgICA8IS0tIDxpbWcgY2xhc3M9XCJjYXJkLXRodW1ibmFpbCB3cy1tYXQtcHJpbWFyeS1saXRlLWJhY2tncm91bmRcIiBbc3JjXT1cImNvbnRlbnQ/LmFwcEljb25cIiBhbHQ9XCJUaHVtYm5haWxcIlxuICAgICAgICAoY2xpY2spPVwiY29udGVudC52aWV3Q2hpbGRyZW4gPSAhY29udGVudC52aWV3Q2hpbGRyZW5cIiBbd3NVdGlsc0RlZmF1bHRUaHVtYm5haWxdPVwiZGVmYXVsdFRodW1ibmFpbFwiIC8+IC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2wgZmxleC13cmFwIGZsZXgtYmV0d2VlbiB3aWR0aC1leHBhbmQgcHItMCB3LTEwMCBcIj5cblxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXRydW5jYXRlXCIgW25nQ2xhc3NdPVwieydjdXJzb3ItcG9pbnRlcic6ICFpc0VuYWJsZWR9XCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNvbnRlbnQudmlld0NoaWxkcmVuID0gIWNvbnRlbnQudmlld0NoaWxkcmVuXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IHNtOmZsZXgtcm93IGZsZXgtd3JhcFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIWZvclByZXZpZXcgJiYgY29udGVudD8uaWRlbnRpZmllciAmJiBnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKSA7IGVsc2UgZWxzZUJsb2NrXCI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldENvbXBsZXRpb25TdGF0dXMoY29udGVudC5pZGVudGlmaWVyKSA9PSAyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29tcGxldGVkIG1yLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJjb21wbGV0ZWQtaWNvblwiIFtjb2xvcl09XCJibHVlXCI+Y2hlY2tfY2lyY2xlPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldENvbXBsZXRpb25TdGF0dXMoY29udGVudD8uaWRlbnRpZmllcikgPCAyXCI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxjaXJjbGUtcHJvZ3Jlc3MgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBwcm9ncmVzcyBtci0xXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGVyY2VudF09XCJnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKVwiIFtyYWRpdXNdPVwiMTBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZVdpZHRoXT1cIjJcIiBbaW5uZXJTdHJva2VXaWR0aF09XCIyXCIgW3NwYWNlXT1cIi0yXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3V0ZXJTdHJva2VDb2xvcl09XCJwcm9ncmVzc0NvbG9yMigpXCIgW2lubmVyU3Ryb2tlQ29sb3JdPVwiJ3JnYmEoMCwgMCwgMCwgMC4xNiknXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYW5pbWF0aW9uXT1cInRydWVcIiBbYW5pbWF0aW9uRHVyYXRpb25dPVwiMjUwXCIgW3Nob3dUaXRsZV09XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dVbml0c109XCJmYWxzZVwiIFtzaG93U3VidGl0bGVdPVwiZmFsc2VcIiBbc2hvd0lubmVyU3Ryb2tlXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbG9ja3dpc2VdPVwidHJ1ZVwiIFtiYWNrZ3JvdW5kT3BhY2l0eV09XCIwXCIgW2JhY2tncm91bmRHcmFkaWVudF09XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2JhY2tncm91bmRTdHJva2VXaWR0aF09XCIzXCIgbWF0VG9vbHRpcD1cIkluIHByb2dyZXNzXCIgW3Nob3daZXJvT3V0ZXJTdHJva2VdPWZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2JhY2tncm91bmRQYWRkaW5nXT1cIi03XCIgW3N0YXJ0RnJvbVplcm9dPVwiZmFsc2VcIiBbYmFja2dyb3VuZFBhZGRpbmddPVwiMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2ltYWdlSGVpZ2h0XT1cIjE4XCIgW2ltYWdlV2lkdGhdPVwiMThcIiBbc2hvd0JhY2tncm91bmRdPVwiZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZUxpbmVjYXBdPVwiJ2J1dHQnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2NpcmNsZS1wcm9ncmVzcz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNlbHNlQmxvY2s+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxjaXJjbGUtcHJvZ3Jlc3MgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBwcm9ncmVzcyBtci0xXCIgW3BlcmNlbnRdPVwiMFwiIFtyYWRpdXNdPVwiMTFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlV2lkdGhdPVwiMlwiIFtpbm5lclN0cm9rZVdpZHRoXT1cIjJcIiBbb3V0ZXJTdHJva2VDb2xvcl09XCInIzgwODA4MCdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lubmVyU3Ryb2tlQ29sb3JdPVwiJyM4MDgwODAnXCIgW2FuaW1hdGlvbl09XCJ0cnVlXCIgW3NwYWNlXT1cIi0yXCIgW3Nob3dVbml0c109XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYW5pbWF0aW9uRHVyYXRpb25dPVwiMjUwXCIgW3Nob3dUaXRsZV09XCJmYWxzZVwiIFtiYWNrZ3JvdW5kUGFkZGluZ109XCIwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtiYWNrZ3JvdW5kUGFkZGluZ109XCItOVwiIFtvdXRlclN0cm9rZUxpbmVjYXBdPVwiJ2J1dHQnXCIgbWF0VG9vbHRpcD1cIk5vdCBzdGFydGVkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93U3VidGl0bGVdPVwiZmFsc2VcIiBbc2hvd0lubmVyU3Ryb2tlXT1cInRydWVcIiBbY2xvY2t3aXNlXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2ltYWdlSGVpZ2h0XT1cIjIyXCIgW2ltYWdlV2lkdGhdPVwiMjJcIiBbc2hvd0JhY2tncm91bmRdPVwiZmFsc2VcIj48L2NpcmNsZS1wcm9ncmVzcz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IFtuZ0NsYXNzXT1cInsnY29sbGVjdGlvbi1hY3RpdmUtY2xhc3MnOiBwYXRoU2V0Py5oYXMoY29udGVudD8uaWRlbnRpZmllcil9XCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIDxwIGNsYXNzPVwibWFyZ2luLXJlbW92ZSB0ZXh0LXRydW5jYXRlIG1hdC1zdWJoZWFkaW5nLTEgZmxleC1hdXRvIGZvbnQtYm9sZCBub2R0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsndGV4dC1hY3RpdmUnOiBwYXRoU2V0Py5oYXMoY29udGVudC5pZGVudGlmaWVyKX1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2luZGV4fX0uIHt7IGNvbnRlbnQ/Lm5hbWUgfCB0cnVuY2F0ZTo1MCB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9wPiAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwibWFyZ2luLXJlbW92ZSB0ZXh0LXRydW5jYXRlIG1hdC1zdWJoZWFkaW5nLTEgZmxleC1hdXRvIGZvbnQtYm9sZCBub2R0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5kaXNhYmxlZF09XCJudWxsXCIgW25nQ2xhc3NdPVwieydtbC0zJzogaXNFbnJvbGxlZH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtyb3V0ZXJMaW5rXT1cIihpc0FsbG93ZWQgJiYgIWZvclByZXZpZXcgJiYgaXNFbmFibGVkKSA/IHJlc291cmNlTGluay51cmwgOiBudWxsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcXVlcnlQYXJhbXNdPVwiY29tcHV0ZWRRdWVyeVBhcmFtc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0ge3tjb250ZW50Py5jb3Vyc2VDYXRlZ29yeX19IC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgW25nQ2xhc3NdPVwieydyZXNvdXJjZS1hY3RpdmUnOiBwYXRoU2V0Py5oYXMoY29udGVudD8uaWRlbnRpZmllcil9XCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtdHJ1bmNhdGUgXCIgW25nQ2xhc3NdPVwieydjdXJzb3ItcG9pbnRlcic6ICFpc0VuYWJsZWR9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInJhaXNlVGVsZW1ldHJ5KCk7IGNoYW5nZVJlc291cmNlKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2wgc206ZmxleC1yb3cgZmxleC13cmFwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cIm1hcmdpbi1yZW1vdmUgdGV4dC10cnVuY2F0ZSBtYXQtYm9keS0yIGZsZXgtYXV0byBmb250LWJvbGQgbm9kdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J3RleHQtYWN0aXZlJzogcGF0aFNldD8uaGFzKGNvbnRlbnQ/LmlkZW50aWZpZXIpfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21hdFRvb2x0aXBdPVwiY29udGVudD8ubmFtZT8ubGVuZ3RoID4gNTAgPyBjb250ZW50Py5uYW1lIDogJydcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXBQb3NpdGlvbj1cImFib3ZlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSA8bWF0LWljb24gY2xhc3M9XCJtYXJnaW4tcmlnaHQteHMgcmFkaW9idG4gdGltZS1pY29uXCI+cmFkaW9fYnV0dG9uX3VuY2hlY2tlZCA8L21hdC1pY29uPiAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2luZGV4fX0uIHt7IGNvbnRlbnQ/Lm5hbWUgfCB0cnVuY2F0ZTo1MCB9fVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNvbnRlbnQtdHlwZSBvcHRpb25hbC1zcGFuIG5vZHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5vcHRpb25hbFJlYWRpbmdcIj57eyAncGxheWVyYnJpZWYub3B0aW9uYWwnIHwgdHJhbnNsYXRlIHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZWNhc2V9fSA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIGZvciBkZWZhdWx0IGdyZXkgaWNvbnMgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhcGF0aFNldD8uaGFzKGNvbnRlbnQ/LmlkZW50aWZpZXIpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVzaWNvbnMgd3MtbWF0LWJsYWNrNjAtdGV4dFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvdmlkZW8uc3ZnXCIgYWx0PVwiVmlkZW9cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCIgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ3ZpZGVvL21wNCcgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICd2aWRlby94LXlvdXR1YmUnIHx8XG4gICAgICAgICAgICAgICAgICAgICAgY29udGVudD8ubWltZVR5cGUgPT09J2FwcGxpY2F0aW9uL3gtbXBlZ1VSTCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2F1ZGlvLnN2Z1wiIGFsdD1cIkF1ZGlvXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhdWRpby9tcGVnJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvcGRmLnN2Z1wiIGFsdD1cIlBERlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vcGRmJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9yZXNvdXJjZS5zdmdcIiBhbHQ9XCJTdXJ2ZXlcIiBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcbiAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3N1cnZleSdcIj4gLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9saW5rLnN2Z1wiIGFsdD1cIkludGVyYWN0aXZlQ29udGVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLmVrc3RlcC5odG1sLWFyY2hpdmUnIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAndGV4dC94LXVybCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC9ncmV5L2Fzc2Vzc21lbnQuc3ZnXCIgYWx0PVwiQXNzZXNzbWVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vanNvbicgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9xdWl6JyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5zdW5iaXJkLnF1ZXN0aW9uc2V0J1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvaW1hZ2Uuc3ZnXCIgYWx0PVwiSW1hZ2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2ltYWdlL3BuZycgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICdpbWFnZS9qcGVnJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9jb250ZW50L2dyZXkvY29udGVudF9jb3B5LnN2Z1wiIGNsYXNzPVwiY29udGVudGljb25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbHQ9XCJDb3Vyc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi92bmQuZWtzdGVwLmNvbnRlbnQtY29sbGVjdGlvbicgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9zdXJ2ZXknXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9tb2R1bGUuc3ZnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiIGFsdD1cIm9mZmxpbmUgc2Vzc2lvbnNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9vZmZsaW5lJ1wiPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuRklOQUxfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuQ09NUF9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5TVEFOREFMT05FX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlBSQUNUSUNFX1JFU09VUkNFXCI+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJyZXNvdXJjZUR1cmF0aW9uIHdzLW1hdC1ibGFjazYwLXRleHQgbm9kdHJhbnNsYXRlXCI+e3tcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ/Lm1heFF1ZXN0aW9ucyB9fSB7eyAncGxheWVyYnJpZWYucXVlc3Rpb25zJyB8IHRyYW5zbGF0ZSB8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZWNhc2V9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIShjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkZJTkFMX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LkNPTVBfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuU1RBTkRBTE9ORV9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5QUkFDVElDRV9SRVNPVVJDRSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJyZXNvdXJjZUR1cmF0aW9uIHdzLW1hdC1ibGFjazYwLXRleHQgbm9kdHJhbnNsYXRlXCI+e3tcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjb250ZW50Py5kdXJhdGlvbnx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWVyYXJjaHlNYXBEYXRhW2NvbnRlbnQ/LmlkZW50aWZpZXJdPy5leHBlY3RlZER1cmF0aW9uIHx8IDApfFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGlwZUR1cmF0aW9uVHJhbnNmb3JtOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2htcydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gZm9yIHdoaXRlIGljb25zIHdoZW4gY29udGVudCBoaWdobGlnaHRlZCAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInBhdGhTZXQ/Lmhhcyhjb250ZW50Py5pZGVudGlmaWVyKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlc2ljb25zIHdzLW1hdC13aGl0ZS10ZXh0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvd2hpdGUvdmlkZW8uc3ZnXCIgYWx0PVwiVmlkZW9cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCIgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ3ZpZGVvL21wNCcgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICd2aWRlby94LXlvdXR1YmUnIHx8XG4gICAgICAgICAgICAgICAgICAgICAgY29udGVudD8ubWltZVR5cGUgPT09J2FwcGxpY2F0aW9uL3gtbXBlZ1VSTCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9hdWRpby5zdmdcIiBhbHQ9XCJBdWRpb1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXVkaW8vbXBlZydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9wZGYuc3ZnXCIgYWx0PVwiUERGXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9wZGYnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSA8aW1nIHNyYz1cIi9hc3NldHMvaWNvbnMvY29udGVudC93aGl0ZS9yZXNvdXJjZS5zdmdcIiBhbHQ9XCJTdXJ2ZXlcIiBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcbiAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3N1cnZleSdcIj4gLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvd2hpdGUvbGluay5zdmdcIiBhbHQ9XCJJbnRlcmFjdGl2ZUNvbnRlbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsb2F0LWxlZnQgbWFyZ2luLXJpZ2h0LXhzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3ZuZC5la3N0ZXAuaHRtbC1hcmNoaXZlJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ3RleHQveC11cmwnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvd2hpdGUvYXNzZXNzbWVudC5zdmdcIiBhbHQ9XCJBc3Nlc3NtZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbG9hdC1sZWZ0IG1hcmdpbi1yaWdodC14c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9qc29uJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3F1aXonIHx8IGNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vdm5kLnN1bmJpcmQucXVlc3Rpb25zZXQnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvZ3JleS9pbWFnZS5zdmdcIiBhbHQ9XCJJbWFnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQ/Lm1pbWVUeXBlID09PSAnaW1hZ2UvcG5nJyB8fCBjb250ZW50Py5taW1lVHlwZSA9PT0gJ2ltYWdlL2pwZWcnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvd2hpdGUvY29udGVudF9jb3B5LnN2Z1wiIGNsYXNzPVwiY29udGVudGljb25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbHQ9XCJDb3Vyc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImNvbnRlbnQubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi92bmQuZWtzdGVwLmNvbnRlbnQtY29sbGVjdGlvbicgfHwgY29udGVudD8ubWltZVR5cGUgPT09ICdhcHBsaWNhdGlvbi9zdXJ2ZXknXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBzcmM9XCIvYXNzZXRzL2ljb25zL2NvbnRlbnQvd2hpdGUvbW9kdWxlLnN2Z1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxvYXQtbGVmdCBtYXJnaW4tcmlnaHQteHNcIiBhbHQ9XCJvZmZsaW5lIHNlc3Npb25zXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjb250ZW50Lm1pbWVUeXBlID09PSAnYXBwbGljYXRpb24vb2ZmbGluZSdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5GSU5BTF9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5DT01QX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlNUQU5EQUxPTkVfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuUFJBQ1RJQ0VfUkVTT1VSQ0VcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJyZXNvdXJjZUR1cmF0aW9uIHdzLW1hdC13aGl0ZS10ZXh0IG5vZHRyYW5zbGF0ZVwiPnt7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50Py5tYXhRdWVzdGlvbnMgfX0ge3sgJ3BsYXllcmJyaWVmLnF1ZXN0aW9ucycgfCB0cmFuc2xhdGUgfFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGVjYXNlfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiEoY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5GSU5BTF9BU1NFU1NNRU5UIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudC5wcmltYXJ5Q2F0ZWdvcnkgPT09IHByaW1hcnlDYXRlZ29yeS5DT01QX0FTU0VTU01FTlQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50LnByaW1hcnlDYXRlZ29yeSA9PT0gcHJpbWFyeUNhdGVnb3J5LlNUQU5EQUxPTkVfQVNTRVNTTUVOVCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQucHJpbWFyeUNhdGVnb3J5ID09PSBwcmltYXJ5Q2F0ZWdvcnkuUFJBQ1RJQ0VfUkVTT1VSQ0UpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicmVzb3VyY2VEdXJhdGlvbiB3cy1tYXQtd2hpdGUtdGV4dCBub2R0cmFuc2xhdGVcIj57e1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvbnRlbnQ/LmR1cmF0aW9ufHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZXJhcmNoeU1hcERhdGFbY29udGVudD8uaWRlbnRpZmllcl0/LmV4cGVjdGVkRHVyYXRpb24gfHwgMCl8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXBlRHVyYXRpb25UcmFuc2Zvcm06XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnaG1zJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIDxkaXYgY2xhc3M9XCJ0eXBlLWNvbnRhaW5lciByZXNvdXJjZSBtdC0yIHNtOm10LTBcIiAqbmdJZj1cImNvbnRlbnQ/LmNhdGVnb3J5ID09PSAnUmVzb3VyY2UnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwibXItMSBjdXN0b20taWNvbiByb3RhdGUtOTBcIj5jYWxsX3RvX2FjdGlvbjwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJub2R0cmFuc2xhdGVcIj5SZXNvdXJjZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInR5cGUtY29udGFpbmVyIG1vZHVsZSBtdC0yIHNtOm10LTBcIiAqbmdJZj1cImNvbnRlbnQ/LmNhdGVnb3J5ID09PSAnQ29sbGVjdGlvbidcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJtci0xIGN1c3RvbS1pY29uIHJvdGF0ZS05MFwiPmNhbGxfdG9fYWN0aW9uPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5vZHRyYW5zbGF0ZVwiPk1vZHVsZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInR5cGUtY29udGFpbmVyIGNvdXJzZSBtdC0yIHNtOm10LTBcIiAqbmdJZj1cImNvbnRlbnQ/LmNhdGVnb3J5ID09PSAnQ291cnNlJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm1yLTEgY3VzdG9tLWljb24gcm90YXRlLTkwXCI+Y2FsbF90b19hY3Rpb248L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibm9kdHJhbnNsYXRlXCI+Q291cnNlPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+IC0tPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwhLS0gRm9yIGNvdXJzZSBwcm9ncmVzcyB0byBiZSBzaG93biAtLT5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIiFmb3JQcmV2aWV3ICYmIGNvbnRlbnQ/LmlkZW50aWZpZXIgJiYgZ2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcilcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRDb21wbGV0aW9uU3RhdHVzKGNvbnRlbnQ/LmlkZW50aWZpZXIpID09IDJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTIgbXItNCAgZmxleCBmbGV4LTEgZmxleC1jb2wgIHByb2dyZXNzLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1yb3cganVzdGlmeS1lbmQgdy1mdWxsIFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWF0LWJvZHktMiBub2R0cmFuc2xhdGUgXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7Z2V0Q29tcGxldGlvblBlcmNlbnRhZ2UoY29udGVudD8uaWRlbnRpZmllcil9fSU8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHdzLXdpZGdldC1jb250ZW50LXByb2dyZXNzIFtjb250ZW50SWRdPVwiY29udGVudD8ucHJvZ3Jlc3NcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwcm9ncmVzc109XCJnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Byb2dyZXNzVHlwZV09XCIncGVyY2VudGFnZSdcIiBbY3VzdG9tQ2xhc3NOYW1lXT1cIid2aWV3ZXItcHJvZ3Jlc3MnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3dzLXdpZGdldC1jb250ZW50LXByb2dyZXNzPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnQ/Lmlzc3VlZENlcnRpZmljYXRlc0lkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YSBjbGFzcz1cIm1sLTUgY2VydGlmaWNhdGUtYnRuXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J2Rpc2FibGUtYnRuJzogZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmcgfHwgY29udGVudD8uaXNzdWVkQ2VydGlmaWNhdGVzSWR9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiIWRvd25sb2FkQ2VydGlmaWNhdGVMb2FkaW5nICYmIGRvd25sb2FkQ2VydGlmaWNhdGUoY29udGVudD8uaXNzdWVkQ2VydGlmaWNhdGVzSWQpOyRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPGltZyBzcmM9XCJmdXNpb24tYXNzZXRzL2ltYWdlcy9jZXJ0aWZpY2F0ZS1pY28uc3ZnXCIgd2lkdGg9XCIyNFwiIGhlaWdodD1cIjI0XCI+IC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibm9kdHJhbnNsYXRlXCI+Q2VydGlmaWNhdGU8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwiIWRvd25sb2FkQ2VydGlmaWNhdGVMb2FkaW5nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJtbC0yXCI+YXJyb3dfZG93bndhcmQ8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjZW50ZXIgZmxleCBmbGV4LW1pZGRsZSBjZXJ0aWZpY2F0ZS1sb2FkZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImRvd25sb2FkQ2VydGlmaWNhdGVMb2FkaW5nXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtc3Bpbm5lciBzdHJva2VXaWR0aD1cIjJcIiBzdHJva2U9XCInd2hpdGUnXCIgY2xhc3M9XCJ3aGl0ZS1zcGlubmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaWFtZXRlcl09XCIxNlwiPjwvbWF0LXNwaW5uZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPGNpcmNsZS1wcm9ncmVzcyBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHByb2dyZXNzXCIgW3BlcmNlbnRdPVwiMTAwXCIgW3JhZGl1c109XCIxMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZVdpZHRoXT1cIjNcIiBbaW5uZXJTdHJva2VXaWR0aF09XCIzXCIgW3NwYWNlXT1cIi0zXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW291dGVyU3Ryb2tlQ29sb3JdPVwicHJvZ3Jlc3NDb2xvcigpXCIgW2lubmVyU3Ryb2tlQ29sb3JdPVwiJ3JnYmEoMCwwLDAsLjE2KSdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYW5pbWF0aW9uXT1cInRydWVcIiBbYW5pbWF0aW9uRHVyYXRpb25dPVwiMzAwXCIgW3Nob3dUaXRsZV09XCJmYWxzZVwiIFtzaG93VW5pdHNdPVwiZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2hvd1N1YnRpdGxlXT1cImZhbHNlXCIgW3Nob3dJbm5lclN0cm9rZV09XCJ0cnVlXCIgW2Nsb2Nrd2lzZV09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2JhY2tncm91bmRPcGFjaXR5XT1cIjBcIiBbYmFja2dyb3VuZEdyYWRpZW50XT1cImZhbHNlXCIgW2JhY2tncm91bmRTdHJva2VXaWR0aF09XCIzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3daZXJvT3V0ZXJTdHJva2VdPWZhbHNlIFtiYWNrZ3JvdW5kUGFkZGluZ109XCItOVwiIFtzdGFydEZyb21aZXJvXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2JhY2tncm91bmRQYWRkaW5nXT1cIjBcIiBbaW1hZ2VIZWlnaHRdPVwiMjRcIiBbaW1hZ2VXaWR0aF09XCIyNFwiIFtzaG93QmFja2dyb3VuZF09XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvdXRlclN0cm9rZUxpbmVjYXBdPVwiJ2J1dHQnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9jaXJjbGUtcHJvZ3Jlc3M+IC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0Q29tcGxldGlvblN0YXR1cyhjb250ZW50Py5pZGVudGlmaWVyKSA8IDJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTIgbXItNCAgZmxleCBmbGV4LTEgZmxleC1jb2wgIHByb2dyZXNzLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1yb3cganVzdGlmeS1lbmQgdy1mdWxsIHdzLW1hdC1ibGFjay10ZXh0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtYXQtYm9keS0yICB3cy1tYXQtYmxhY2stdGV4dCBub2R0cmFuc2xhdGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tnZXRDb21wbGV0aW9uUGVyY2VudGFnZShjb250ZW50Py5pZGVudGlmaWVyKX19JTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8d3Mtd2lkZ2V0LWNvbnRlbnQtcHJvZ3Jlc3MgW2NvbnRlbnRJZF09XCJjb250ZW50Py5wcm9ncmVzc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Byb2dyZXNzXT1cImdldENvbXBsZXRpb25QZXJjZW50YWdlKGNvbnRlbnQ/LmlkZW50aWZpZXIpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcHJvZ3Jlc3NUeXBlXT1cIidwZXJjZW50YWdlJ1wiIFtjdXN0b21DbGFzc05hbWVdPVwiJ3ZpZXdlci1wcm9ncmVzcydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvd3Mtd2lkZ2V0LWNvbnRlbnQtcHJvZ3Jlc3M+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudD8uaXNzdWVkQ2VydGlmaWNhdGVzSWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwibWwtNSBjZXJ0aWZpY2F0ZS1idG5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnZGlzYWJsZS1idG4nOiBkb3dubG9hZENlcnRpZmljYXRlTG9hZGluZyB8fCBjb250ZW50Py5pc3N1ZWRDZXJ0aWZpY2F0ZXNJZH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCIhZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmcgJiYgZG93bmxvYWRDZXJ0aWZpY2F0ZShjb250ZW50Py5pc3N1ZWRDZXJ0aWZpY2F0ZXNJZCk7JGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSA8aW1nIHNyYz1cImZ1c2lvbi1hc3NldHMvaW1hZ2VzL2NlcnRpZmljYXRlLWljby5zdmdcIiB3aWR0aD1cIjI0XCIgaGVpZ2h0PVwiMjRcIj4gLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJub2R0cmFuc2xhdGVcIj5DZXJ0aWZpY2F0ZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCIhZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1sLTJcIj5hcnJvd19kb3dud2FyZDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNlbnRlciBmbGV4IGZsZXgtbWlkZGxlIGNlcnRpZmljYXRlLWxvYWRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZG93bmxvYWRDZXJ0aWZpY2F0ZUxvYWRpbmdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zcGlubmVyIHN0cm9rZVdpZHRoPVwiMlwiIHN0cm9rZT1cIid3aGl0ZSdcIiBjbGFzcz1cIndoaXRlLXNwaW5uZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2RpYW1ldGVyXT1cIjE2XCI+PC9tYXQtc3Bpbm5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICA8IS0tIDxkaXYgY2xhc3M9XCJzZWUtYWxsLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICA8YSBocmVmPVwiamF2YXNjcmlwdDp2b2lkKDApXCIgcm9sZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiY29udGVudC52aWV3Q2hpbGRyZW4gPSAhY29udGVudC52aWV3Q2hpbGRyZW47IGV4cGFuZEFjdGl2ZSA9IGZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwic2VlLWFsbC1idG4gdGFiIGN1c3RvbS1jaGV2cm9uIGN1c3RvbWljb25cIiBtYXQtYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwiIWNvbnRlbnQudmlld0NoaWxkcmVuICYmICFpc01vZHVsZVwiPmtleWJvYXJkX2Fycm93X2Rvd248L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwiY29udGVudC52aWV3Q2hpbGRyZW4gJiYgIWlzTW9kdWxlXCI+a2V5Ym9hcmRfYXJyb3dfdXA8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwiIWNvbnRlbnQudmlld0NoaWxkcmVuICYmIGlzTW9kdWxlXCI+YWRkPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cImNvbnRlbnQudmlld0NoaWxkcmVuICYmIGlzTW9kdWxlXCI+cmVtb3ZlPC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgIDwvZGl2PiAtLT5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cblxuPC9uZy1jb250YWluZXI+Il19