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