@recursyve/nice-ui-kit.v2 15.0.0-beta.131 → 16.0.0-beta.134
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/animations/defaults.mjs +32 -0
- package/{esm2020 → esm2022}/lib/api/interceptors/transform-response.interceptor.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/alert/alert.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/alert/alert.module.mjs +9 -9
- package/{esm2020 → esm2022}/lib/components/alert/alert.service.mjs +4 -4
- package/esm2022/lib/components/assets-carousel/assets-carousel.component.mjs +283 -0
- package/{esm2020 → esm2022}/lib/components/assets-carousel/assets-carousel.module.mjs +19 -19
- package/{esm2020 → esm2022}/lib/components/assets-carousel/directives/assets-carousel-active-content.directive.mjs +4 -4
- package/esm2022/lib/components/async-typeahead/async-typeahead.component.mjs +451 -0
- package/{esm2020 → esm2022}/lib/components/async-typeahead/async-typeahead.module.mjs +21 -21
- package/{esm2020 → esm2022}/lib/components/async-typeahead/providers/async-typeahead.service.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/base-form/base-form.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/base-form/base-form.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/components/base-form/form-submit.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/card/card.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/card/card.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/components/carousel/carousel.component.mjs +4 -4
- package/esm2022/lib/components/carousel/carousel.module.mjs +40 -0
- package/{esm2020 → esm2022}/lib/components/carousel/picture-modal/picture-modal.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/carousel/picture-modal/picture-modal.service.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/carousel/pipe/carousel-layout.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/collapsable/collapsable.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/collapsable/collapsable.module.mjs +7 -7
- package/{esm2020 → esm2022}/lib/components/date-range-picker/components/header/header.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/date-range-picker/components/range-preset/range-preset.component.mjs +4 -4
- package/esm2022/lib/components/date-range-picker/date-range-picker.component.mjs +95 -0
- package/{esm2020 → esm2022}/lib/components/date-range-picker/date-range-picker.module.mjs +21 -21
- package/{esm2020 → esm2022}/lib/components/date-range-picker/providers/date-range-picker.service.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/drawer/drawer.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/drawer/drawer.module.mjs +7 -7
- package/{esm2020 → esm2022}/lib/components/drawer/drawer.service.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/export-bottom-sheet/export-bottom-sheet.component.mjs +4 -4
- package/esm2022/lib/components/export-bottom-sheet/export-bottom-sheet.module.mjs +45 -0
- package/{esm2020 → esm2022}/lib/components/export-bottom-sheet/providers/export-bottom-sheet.service.mjs +7 -7
- package/{esm2020 → esm2022}/lib/components/form-error/control-status.directive.mjs +4 -4
- package/esm2022/lib/components/form-error/form-error.component.mjs +53 -0
- package/{esm2020 → esm2022}/lib/components/form-error/form-error.module.mjs +5 -5
- package/esm2022/lib/components/horizontal-stepper/horizontal-stepper.component.mjs +34 -0
- package/{esm2020 → esm2022}/lib/components/horizontal-stepper/horizontal-stepper.module.mjs +9 -9
- package/{esm2020 → esm2022}/lib/components/horizontal-stepper/step.component.mjs +6 -6
- package/esm2022/lib/components/image-cropper/image-cropper.component.mjs +1269 -0
- package/{esm2020 → esm2022}/lib/components/image-cropper/image-cropper.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/components/layout/layout.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/layout/layout.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/components/loading-spinner/loading-spinner.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/loading-spinner/loading-spinner.module.mjs +9 -9
- package/{esm2020 → esm2022}/lib/components/loading-spinner/loading.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/loading-toast/loading-toast.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/loading-toast/loading-toast.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/loading-toast/loading-toast.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/components/loading-toast/loading-toast.service.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/lottie/lottie.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/lottie/lottie.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/components/navigation/components/hint-component-base.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/navigation/directives/show-hint.directive.mjs +4 -4
- package/esm2022/lib/components/navigation/horizontal/components/basic/basic.component.mjs +62 -0
- package/{esm2020 → esm2022}/lib/components/navigation/horizontal/components/branch/branch.component.mjs +7 -7
- package/{esm2020 → esm2022}/lib/components/navigation/horizontal/components/divider/divider.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/navigation/horizontal/components/spacer/spacer.component.mjs +4 -4
- package/esm2022/lib/components/navigation/horizontal/horizontal.component.mjs +50 -0
- package/esm2022/lib/components/navigation/navigation.component.mjs +83 -0
- package/esm2022/lib/components/navigation/navigation.module.mjs +108 -0
- package/{esm2020 → esm2022}/lib/components/navigation/navigation.service.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/navigation/pipes/should-hide.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/navigation/pipes/should-show-hint.pipe.mjs +4 -4
- package/esm2022/lib/components/navigation/pipes/translate-with-context.pipe.mjs +25 -0
- package/{esm2020 → esm2022}/lib/components/navigation/providers/hint.service.mjs +4 -4
- package/esm2022/lib/components/navigation/providers/translation-context.service.mjs +16 -0
- package/{esm2020 → esm2022}/lib/components/navigation/vertical/components/aside/aside.component.mjs +6 -6
- package/esm2022/lib/components/navigation/vertical/components/basic/basic.component.mjs +76 -0
- package/{esm2020 → esm2022}/lib/components/navigation/vertical/components/collapsable/collapsable.component.mjs +8 -8
- package/{esm2020 → esm2022}/lib/components/navigation/vertical/components/divider/divider.component.mjs +4 -4
- package/esm2022/lib/components/navigation/vertical/components/group/group.component.mjs +75 -0
- package/{esm2020 → esm2022}/lib/components/navigation/vertical/components/spacer/spacer.component.mjs +4 -4
- package/esm2022/lib/components/navigation/vertical/vertical.component.mjs +599 -0
- package/esm2022/lib/components/search-bar/search-bar.component.mjs +76 -0
- package/{esm2020 → esm2022}/lib/components/search-bar/search-bar.module.mjs +13 -13
- package/{esm2020 → esm2022}/lib/components/sweet-alert/sweet-alert.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/sweet-alert/sweet-alert.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/sweet-alert/sweet-alert.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/components/sweet-alert/sweet-alert.service.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/toast/toast.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/toast/toast.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/components/toast/toast.service.mjs +4 -4
- package/esm2022/lib/components/toggle-button-group/toggle-button-group.component.mjs +134 -0
- package/{esm2020 → esm2022}/lib/components/toggle-button-group/toggle-button-group.module.mjs +7 -7
- package/{esm2020 → esm2022}/lib/components/toggle-button-group/toggle-button.component.mjs +4 -4
- package/esm2022/lib/components/translation-form/components/textarea/translation-form-textarea.component.mjs +38 -0
- package/esm2022/lib/components/translation-form/components/textfield/translation-form-textfield.component.mjs +26 -0
- package/{esm2020 → esm2022}/lib/components/translation-form/components/translation-form.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/translation-form/components/translation-form.module.mjs +19 -19
- package/{esm2020 → esm2022}/lib/components/translation-form/directives/translation-context.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/translation-form/providers/nice-translation-form.service.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/translation-form/toggle/translation-toggle.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/translation-form/validators/require-for-languages.validator.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/typeahead/directives/options-scroll.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/typeahead/directives/options-scroll.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/components/typeahead/typeahead.component.mjs +9 -9
- package/{esm2020 → esm2022}/lib/components/typeahead/typeahead.module.mjs +25 -25
- package/{esm2020 → esm2022}/lib/directives/autofocus/autofocus.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/directives/autofocus/autofocus.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/directives/autogrow/autogrow.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/directives/autogrow/autogrow.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/directives/chip-async-typeahead/chip-async-typeahead.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/directives/chip-list/chip-list-items/chip-list-item-label.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/directives/chip-list/chip-list-items/chip-list-items.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/directives/chip-list/chip-list.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/directives/chip-list/chip-list.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/directives/draggable-list/draggable-list.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/directives/draggable-list/draggable-list.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/directives/dropzone/dropzone.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/directives/dropzone/dropzone.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/directives/image-error-placeholder/image-error-placeholder.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/directives/image-error-placeholder/image-error-placeholder.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/directives/material/material.module.mjs +7 -7
- package/{esm2020 → esm2022}/lib/directives/material/nice-material-style.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/directives/material/nice-rounded-style.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/directives/modals/modal-on-click.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/directives/modals/modal-opener.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/directives/rerender/rerender.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/directives/resolve/resolve.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/directives/scroll-reset/scroll-reset.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/directives/scroll-reset/scroll-reset.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/directives/scrollbar/scrollbar.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/directives/scrollbar/scrollbar.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/directives/stop-propagation/click-stop-propagation.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/directives/stop-propagation/stop-propagation.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/directives/window/prevent-close-window.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/directives/window/window-directive.module.mjs +5 -5
- package/esm2022/lib/nice.module.mjs +124 -0
- package/{esm2020 → esm2022}/lib/pipes/boolean.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/pipes/capitalize-first-letter.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/pipes/ceil.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/pipes/entries.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/pipes/find-by-key.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/pipes/first-letter.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/pipes/floor.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/pipes/join-if-defined.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/pipes/link.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/pipes/localized-boolean.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/pipes/localized-currency.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/pipes/localized-date-only.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/pipes/localized-date.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/pipes/minutes-to-time.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/pipes/number-to-ordinal-indicator.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/pipes/pad.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/pipes/phone.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/pipes/pipes.module.mjs +72 -72
- package/{esm2020 → esm2022}/lib/pipes/postal-code.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/pipes/range.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/pipes/round.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/pipes/sanitize-bypass.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/pipes/seconds-to-time.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/pipes/track-by-prop.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/providers/config/config.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/providers/config/config.service.mjs +4 -4
- package/{esm2020 → esm2022}/lib/providers/media-watcher/media-watcher.module.mjs +7 -7
- package/{esm2020 → esm2022}/lib/providers/media-watcher/media-watcher.service.mjs +4 -4
- package/{esm2020 → esm2022}/lib/providers/overlay/dynamic-overlay-container.service.mjs +4 -4
- package/{esm2020 → esm2022}/lib/providers/overlay/dynamic-overlay.service.mjs +4 -4
- package/{esm2020 → esm2022}/lib/providers/splash-screen/splash-screen.module.mjs +7 -7
- package/{esm2020 → esm2022}/lib/providers/splash-screen/splash-screen.service.mjs +4 -4
- package/{esm2020 → esm2022}/lib/providers/utils/utils.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/providers/utils/utils.service.mjs +4 -4
- package/esm2022/lib/utils/regex.utils.mjs +11 -0
- package/{fesm2020 → fesm2022}/recursyve-nice-ui-kit.v2.mjs +948 -905
- package/fesm2022/recursyve-nice-ui-kit.v2.mjs.map +1 -0
- package/lib/components/alert/alert.component.d.ts +1 -1
- package/lib/components/assets-carousel/assets-carousel.component.d.ts +1 -1
- package/lib/components/async-typeahead/async-typeahead.component.d.ts +1 -1
- package/lib/components/base-form/base-form.component.d.ts +1 -1
- package/lib/components/base-form/form-submit.directive.d.ts +1 -1
- package/lib/components/card/card.component.d.ts +1 -1
- package/lib/components/carousel/carousel.component.d.ts +1 -1
- package/lib/components/collapsable/collapsable.component.d.ts +1 -1
- package/lib/components/date-range-picker/date-range-picker.component.d.ts +1 -1
- package/lib/components/drawer/drawer.component.d.ts +1 -1
- package/lib/components/form-error/form-error.component.d.ts +1 -1
- package/lib/components/image-cropper/image-cropper.component.d.ts +2 -2
- package/lib/components/loading-spinner/loading-spinner.component.d.ts +1 -1
- package/lib/components/loading-spinner/loading.directive.d.ts +1 -1
- package/lib/components/loading-toast/loading-toast.component.d.ts +1 -1
- package/lib/components/loading-toast/loading-toast.directive.d.ts +1 -1
- package/lib/components/lottie/lottie.component.d.ts +1 -1
- package/lib/components/navigation/directives/show-hint.directive.d.ts +1 -1
- package/lib/components/navigation/horizontal/components/basic/basic.component.d.ts +1 -1
- package/lib/components/navigation/horizontal/components/branch/branch.component.d.ts +1 -1
- package/lib/components/navigation/horizontal/components/divider/divider.component.d.ts +1 -1
- package/lib/components/navigation/horizontal/components/spacer/spacer.component.d.ts +1 -1
- package/lib/components/navigation/horizontal/horizontal.component.d.ts +4 -2
- package/lib/components/navigation/navigation.component.d.ts +3 -1
- package/lib/components/navigation/navigation.module.d.ts +12 -11
- package/lib/components/navigation/pipes/translate-with-context.pipe.d.ts +12 -0
- package/lib/components/navigation/providers/translation-context.service.d.ts +8 -0
- package/lib/components/navigation/vertical/components/aside/aside.component.d.ts +1 -1
- package/lib/components/navigation/vertical/components/basic/basic.component.d.ts +1 -1
- package/lib/components/navigation/vertical/components/collapsable/collapsable.component.d.ts +1 -1
- package/lib/components/navigation/vertical/components/divider/divider.component.d.ts +1 -1
- package/lib/components/navigation/vertical/components/group/group.component.d.ts +1 -1
- package/lib/components/navigation/vertical/components/spacer/spacer.component.d.ts +1 -1
- package/lib/components/navigation/vertical/vertical.component.d.ts +4 -2
- package/lib/components/search-bar/search-bar.component.d.ts +1 -1
- package/lib/components/sweet-alert/sweet-alert.directive.d.ts +1 -1
- package/lib/components/toggle-button-group/toggle-button-group.component.d.ts +1 -1
- package/lib/components/toggle-button-group/toggle-button.component.d.ts +1 -1
- package/lib/components/translation-form/components/textarea/translation-form-textarea.component.d.ts +1 -1
- package/lib/components/translation-form/components/translation-form.component.d.ts +1 -1
- package/lib/components/translation-form/validators/require-for-languages.validator.d.ts +1 -1
- package/lib/components/typeahead/directives/options-scroll.directive.d.ts +1 -1
- package/lib/components/typeahead/typeahead.component.d.ts +1 -1
- package/lib/directives/autogrow/autogrow.directive.d.ts +1 -1
- package/lib/directives/chip-list/chip-list-items/chip-list-items.component.d.ts +1 -1
- package/lib/directives/chip-list/chip-list.directive.d.ts +1 -1
- package/lib/directives/draggable-list/draggable-list.directive.d.ts +1 -1
- package/lib/directives/image-error-placeholder/image-error-placeholder.directive.d.ts +1 -1
- package/lib/directives/modals/modal-opener.directive.d.ts +1 -1
- package/lib/directives/rerender/rerender.directive.d.ts +1 -1
- package/lib/directives/resolve/resolve.directive.d.ts +1 -1
- package/lib/directives/scrollbar/scrollbar.directive.d.ts +1 -1
- package/package.json +12 -19
- package/esm2020/lib/animations/defaults.mjs +0 -32
- package/esm2020/lib/components/assets-carousel/assets-carousel.component.mjs +0 -283
- package/esm2020/lib/components/async-typeahead/async-typeahead.component.mjs +0 -451
- package/esm2020/lib/components/carousel/carousel.module.mjs +0 -41
- package/esm2020/lib/components/date-range-picker/date-range-picker.component.mjs +0 -95
- package/esm2020/lib/components/export-bottom-sheet/export-bottom-sheet.module.mjs +0 -45
- package/esm2020/lib/components/form-error/form-error.component.mjs +0 -53
- package/esm2020/lib/components/horizontal-stepper/horizontal-stepper.component.mjs +0 -34
- package/esm2020/lib/components/image-cropper/image-cropper.component.mjs +0 -1269
- package/esm2020/lib/components/navigation/horizontal/components/basic/basic.component.mjs +0 -62
- package/esm2020/lib/components/navigation/horizontal/horizontal.component.mjs +0 -46
- package/esm2020/lib/components/navigation/navigation.component.mjs +0 -76
- package/esm2020/lib/components/navigation/navigation.module.mjs +0 -105
- package/esm2020/lib/components/navigation/vertical/components/basic/basic.component.mjs +0 -76
- package/esm2020/lib/components/navigation/vertical/components/group/group.component.mjs +0 -75
- package/esm2020/lib/components/navigation/vertical/vertical.component.mjs +0 -595
- package/esm2020/lib/components/search-bar/search-bar.component.mjs +0 -76
- package/esm2020/lib/components/toggle-button-group/toggle-button-group.component.mjs +0 -134
- package/esm2020/lib/components/translation-form/components/textarea/translation-form-textarea.component.mjs +0 -38
- package/esm2020/lib/components/translation-form/components/textfield/translation-form-textfield.component.mjs +0 -26
- package/esm2020/lib/nice.module.mjs +0 -124
- package/esm2020/lib/utils/regex.utils.mjs +0 -11
- package/fesm2015/recursyve-nice-ui-kit.v2.mjs +0 -11867
- package/fesm2015/recursyve-nice-ui-kit.v2.mjs.map +0 -1
- package/fesm2020/recursyve-nice-ui-kit.v2.mjs.map +0 -1
- /package/{esm2020 → esm2022}/lib/animations/expand-collapse.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/animations/fade.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/animations/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/animations/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/animations/shake.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/animations/slide.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/animations/zoom.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/api/exceptions/api.exception.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/api/exceptions/exception.factory.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/api/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/api/nice.api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/api/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/alert/alert.types.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/alert/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/alert/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/assets-carousel/assets-carousel.constant.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/assets-carousel/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/assets-carousel/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/async-typeahead/async-typeahead.constant.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/async-typeahead/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/async-typeahead/providers/async-typeahead.provider.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/async-typeahead/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/base-form/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/base-form/nice-base.form.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/base-form/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/card/card.types.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/card/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/card/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/carousel/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/carousel/picture-modal/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/carousel/picture-modal/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/carousel/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/collapsable/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/collapsable/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/date-range-picker/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/date-range-picker/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/drawer/drawer.types.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/drawer/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/drawer/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/export-bottom-sheet/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/export-bottom-sheet/models/export-strategy.model.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/export-bottom-sheet/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/form-error/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/form-error/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/horizontal-stepper/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/horizontal-stepper/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/image-cropper/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/image-cropper/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/image-cropper/resize-canvas.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/layout/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/layout/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/loading-spinner/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/loading-spinner/loading.constant.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/loading-spinner/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/loading-toast/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/loading-toast/loading-toast.constant.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/loading-toast/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/loading-toast/rxjs/show-loading-toast.operator.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/lottie/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/lottie/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/navigation/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/navigation/navigation.types.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/navigation/providers/hide-item.resolver.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/navigation/providers/hint.resolver.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/navigation/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/search-bar/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/search-bar/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/sweet-alert/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/sweet-alert/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/sweet-alert/sweet-alert.constant.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/toast/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/toast/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/toast/rxjs/show-success-or-error-toast.operator.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/toast/rxjs/show-toast.operator.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/toast/toast.constant.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/toggle-button-group/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/toggle-button-group/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/translation-form/decorators/translation-form-group.decorator.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/translation-form/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/translation-form/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/translation-form/translation.form.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/typeahead/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/components/typeahead/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/autofocus/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/autofocus/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/autogrow/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/autogrow/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/chip-async-typeahead/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/chip-async-typeahead/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/chip-list/chip-list.constant.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/chip-list/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/chip-list/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/draggable-list/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/draggable-list/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/dropzone/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/dropzone/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/image-error-placeholder/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/image-error-placeholder/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/material/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/material/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/modals/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/modals/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/rerender/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/rerender/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/resolve/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/resolve/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/scroll-reset/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/scroll-reset/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/scrollbar/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/scrollbar/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/scrollbar/scrollbar.types.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/stop-propagation/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/stop-propagation/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/window/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/directives/window/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/pipes/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/pipes/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/providers/config/config.constants.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/providers/config/config.model.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/providers/config/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/providers/config/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/providers/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/providers/media-watcher/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/providers/media-watcher/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/providers/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/providers/splash-screen/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/providers/splash-screen/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/providers/utils/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/providers/utils/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/types/constructor.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/array.utils.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/case.utils.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/colors.utils.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/date.utils.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/file.utils.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/font-awesome.utils.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/form-data.utils.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/http-status.utils.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/keyboard.utils.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/lexorank.utils.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/modal.utils.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/number.utils.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/object.utils.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/promise.utils.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/query-params.utils.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/type.utils.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/utils/url.utils.mjs +0 -0
- /package/{esm2020 → esm2022}/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/recursyve-nice-ui-kit.v2.mjs +0 -0
|
@@ -1,1269 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Adapted from https://github.com/A-l-y-l-e/Alyle-UI/tree/10.5.3/src/lib/image-cropper
|
|
3
|
-
*/
|
|
4
|
-
import { normalizePassiveListenerOptions } from "@angular/cdk/platform";
|
|
5
|
-
import { ViewportRuler } from "@angular/cdk/scrolling";
|
|
6
|
-
import { DOCUMENT } from "@angular/common";
|
|
7
|
-
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, HostBinding, Inject, Input, NgZone, Output, Renderer2, ViewChild, ViewEncapsulation } from "@angular/core";
|
|
8
|
-
import { Observable, Subject } from "rxjs";
|
|
9
|
-
import { take, takeUntil } from "rxjs/operators";
|
|
10
|
-
import { resizeCanvas } from "./resize-canvas";
|
|
11
|
-
import * as i0 from "@angular/core";
|
|
12
|
-
import * as i1 from "@angular/cdk/scrolling";
|
|
13
|
-
import * as i2 from "@angular/common";
|
|
14
|
-
import * as i3 from "@angular/material/button";
|
|
15
|
-
import * as i4 from "@angular/material/icon";
|
|
16
|
-
const activeEventOptions = normalizePassiveListenerOptions({ passive: false });
|
|
17
|
-
/** Image Cropper Config */
|
|
18
|
-
export class ImgCropperConfig {
|
|
19
|
-
constructor() {
|
|
20
|
-
/** Cropper area width */
|
|
21
|
-
this.width = 250;
|
|
22
|
-
/** Cropper area height */
|
|
23
|
-
this.height = 200;
|
|
24
|
-
this.minWidth = 40;
|
|
25
|
-
this.minHeight = 40;
|
|
26
|
-
/**
|
|
27
|
-
* Set anti-aliased (default: true)
|
|
28
|
-
* @deprecated this is not necessary as the cropper will automatically resize the image
|
|
29
|
-
* to the best quality
|
|
30
|
-
*/
|
|
31
|
-
this.antiAliased = true;
|
|
32
|
-
this.output = ImgResolution.Default;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
/** Image output */
|
|
36
|
-
export var ImgResolution;
|
|
37
|
-
(function (ImgResolution) {
|
|
38
|
-
/**
|
|
39
|
-
* The output image will be equal to the initial size of the cropper area.
|
|
40
|
-
*/
|
|
41
|
-
ImgResolution[ImgResolution["Default"] = 0] = "Default";
|
|
42
|
-
/** Just crop the image without resizing */
|
|
43
|
-
ImgResolution[ImgResolution["OriginalImage"] = 1] = "OriginalImage";
|
|
44
|
-
})(ImgResolution || (ImgResolution = {}));
|
|
45
|
-
/** Image output */
|
|
46
|
-
export var ImgCropperError;
|
|
47
|
-
(function (ImgCropperError) {
|
|
48
|
-
/** The loaded image exceeds the size limit set. */
|
|
49
|
-
ImgCropperError[ImgCropperError["Size"] = 0] = "Size";
|
|
50
|
-
/** The file loaded is not image. */
|
|
51
|
-
ImgCropperError[ImgCropperError["Type"] = 1] = "Type";
|
|
52
|
-
/** When the image has not been loaded. */
|
|
53
|
-
ImgCropperError[ImgCropperError["Other"] = 2] = "Other";
|
|
54
|
-
})(ImgCropperError || (ImgCropperError = {}));
|
|
55
|
-
export class NiceImageCropperComponent {
|
|
56
|
-
set config(val) {
|
|
57
|
-
this._config = mergeDeep({}, new ImgCropperConfig(), val);
|
|
58
|
-
this._configPrimary = mergeDeep({}, this._config);
|
|
59
|
-
this._primaryAreaWidth = this.config.width;
|
|
60
|
-
this._primaryAreaHeight = this.config.height;
|
|
61
|
-
if (this._config.round
|
|
62
|
-
&& this.config.width !== this.config.height) {
|
|
63
|
-
throw new Error(`${NiceImageCropperComponent.и}: Both width and height must be equal when using \`ImgCropperConfig.round = true\``);
|
|
64
|
-
}
|
|
65
|
-
const maxFileSize = this._config.maxFileSize;
|
|
66
|
-
if (maxFileSize) {
|
|
67
|
-
this.maxFileSize = maxFileSize;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
get config() {
|
|
71
|
-
return this._config;
|
|
72
|
-
}
|
|
73
|
-
/** Set scale */
|
|
74
|
-
set scale(val) {
|
|
75
|
-
this.setScale(val);
|
|
76
|
-
}
|
|
77
|
-
get scale() {
|
|
78
|
-
return this._scale;
|
|
79
|
-
}
|
|
80
|
-
/** Get min scale */
|
|
81
|
-
get minScale() {
|
|
82
|
-
return this._minScale;
|
|
83
|
-
}
|
|
84
|
-
constructor(_renderer, _elementRef, cd, _ngZone, _document, viewPortRuler) {
|
|
85
|
-
this._renderer = _renderer;
|
|
86
|
-
this._elementRef = _elementRef;
|
|
87
|
-
this.cd = cd;
|
|
88
|
-
this._ngZone = _ngZone;
|
|
89
|
-
this._imgRect = {};
|
|
90
|
-
this._rotation = 0;
|
|
91
|
-
this.scaleChange = new EventEmitter();
|
|
92
|
-
/** Emits minimum supported image scale */
|
|
93
|
-
// tslint:disable-next-line:no-output-rename
|
|
94
|
-
this.minScaleChange = new EventEmitter();
|
|
95
|
-
/** Emits maximum supported image scale */
|
|
96
|
-
// tslint:disable-next-line:no-output-rename
|
|
97
|
-
this.maxScaleChange = new EventEmitter();
|
|
98
|
-
/** Emits when the image is loaded */
|
|
99
|
-
this.imageLoaded = new EventEmitter();
|
|
100
|
-
/** Emits when the cropper is ready to be interacted */
|
|
101
|
-
this.ready = new EventEmitter();
|
|
102
|
-
/** On crop new image */
|
|
103
|
-
this.cropped = new EventEmitter();
|
|
104
|
-
/** Emits when the cropper is cleaned */
|
|
105
|
-
this.cleaned = new EventEmitter();
|
|
106
|
-
/** Emit an error when the loaded image is not valid */
|
|
107
|
-
// tslint:disable-next-line: no-output-native
|
|
108
|
-
this.error = new EventEmitter();
|
|
109
|
-
/** Emits whenever the component is destroyed. */
|
|
110
|
-
this._destroy = new Subject();
|
|
111
|
-
this._pointerDown = (event) => {
|
|
112
|
-
// Don't do anything if the
|
|
113
|
-
// user is using anything other than the main mouse button.
|
|
114
|
-
if (this._isSliding || (!isTouchEvent(event) && event.button !== 0)) {
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
this._ngZone.run(() => {
|
|
118
|
-
this._isSliding = true;
|
|
119
|
-
this.offset = {
|
|
120
|
-
x: this._imgRect.x,
|
|
121
|
-
y: this._imgRect.y,
|
|
122
|
-
left: this._imgRect.xc,
|
|
123
|
-
top: this._imgRect.yc
|
|
124
|
-
};
|
|
125
|
-
this._lastPointerEvent = event;
|
|
126
|
-
this._startPointerEvent = getGesturePointFromEvent(event);
|
|
127
|
-
event.preventDefault();
|
|
128
|
-
this._bindGlobalEvents(event);
|
|
129
|
-
});
|
|
130
|
-
};
|
|
131
|
-
/**
|
|
132
|
-
* Called when the user has moved their pointer after
|
|
133
|
-
* starting to drag.
|
|
134
|
-
*/
|
|
135
|
-
this._pointerMove = (event) => {
|
|
136
|
-
if (this._isSliding) {
|
|
137
|
-
event.preventDefault();
|
|
138
|
-
this._lastPointerEvent = event;
|
|
139
|
-
let x;
|
|
140
|
-
let y;
|
|
141
|
-
const canvas = this._imgCanvas.nativeElement;
|
|
142
|
-
const scaleFix = this._scal3Fix;
|
|
143
|
-
const config = this.config;
|
|
144
|
-
const startP = this.offset;
|
|
145
|
-
const point = getGesturePointFromEvent(event);
|
|
146
|
-
const deltaX = point.x - this._startPointerEvent.x;
|
|
147
|
-
const deltaY = point.y - this._startPointerEvent.y;
|
|
148
|
-
if (!scaleFix || !startP) {
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
const isMinScaleY = canvas.height * scaleFix < config.height && config.extraZoomOut;
|
|
152
|
-
const isMinScaleX = canvas.width * scaleFix < config.width && config.extraZoomOut;
|
|
153
|
-
const limitLeft = (config.width / 2 / scaleFix) >= startP.left - (deltaX / scaleFix);
|
|
154
|
-
const limitRight = (config.width / 2 / scaleFix) +
|
|
155
|
-
(canvas.width) - (startP.left - (deltaX / scaleFix)) <= config.width / scaleFix;
|
|
156
|
-
const limitTop = ((config.height / 2 / scaleFix) >= (startP.top - (deltaY / scaleFix)));
|
|
157
|
-
const limitBottom = (((config.height / 2 / scaleFix) + (canvas.height) - (startP.top - (deltaY / scaleFix))) <= (config.height / scaleFix));
|
|
158
|
-
// Limit for left
|
|
159
|
-
if ((limitLeft && !isMinScaleX) || (!limitLeft && isMinScaleX)) {
|
|
160
|
-
x = startP.x + (startP.left) - (config.width / 2 / scaleFix);
|
|
161
|
-
}
|
|
162
|
-
// Limit for right
|
|
163
|
-
if ((limitRight && !isMinScaleX) || (!limitRight && isMinScaleX)) {
|
|
164
|
-
x = startP.x + (startP.left) + (config.width / 2 / scaleFix) - canvas.width;
|
|
165
|
-
}
|
|
166
|
-
// Limit for top
|
|
167
|
-
if ((limitTop && !isMinScaleY) || (!limitTop && isMinScaleY)) {
|
|
168
|
-
y = startP.y + (startP.top) - (config.height / 2 / scaleFix);
|
|
169
|
-
}
|
|
170
|
-
// Limit for bottom
|
|
171
|
-
if ((limitBottom && !isMinScaleY) || (!limitBottom && isMinScaleY)) {
|
|
172
|
-
y = startP.y + (startP.top) + (config.height / 2 / scaleFix) - canvas.height;
|
|
173
|
-
}
|
|
174
|
-
// When press shiftKey, deprecated
|
|
175
|
-
// if (event.srcEvent && event.srcEvent.shiftKey) {
|
|
176
|
-
// if (Math.abs(event.deltaX) === Math.max(Math.abs(event.deltaX), Math.abs(event.deltaY))) {
|
|
177
|
-
// y = this.offset.top;
|
|
178
|
-
// } else {
|
|
179
|
-
// x = this.offset.left;
|
|
180
|
-
// }
|
|
181
|
-
// }
|
|
182
|
-
if (x === void 0) {
|
|
183
|
-
x = (deltaX / scaleFix) + (startP.x);
|
|
184
|
-
}
|
|
185
|
-
if (y === void 0) {
|
|
186
|
-
y = (deltaY / scaleFix) + (startP.y);
|
|
187
|
-
}
|
|
188
|
-
this._setStylesForContImg({
|
|
189
|
-
x, y
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
};
|
|
193
|
-
/** Called when the user has lifted their pointer. */
|
|
194
|
-
this._pointerUp = (event) => {
|
|
195
|
-
if (this._isSliding) {
|
|
196
|
-
event.preventDefault();
|
|
197
|
-
this._removeGlobalEvents();
|
|
198
|
-
this._isSliding = false;
|
|
199
|
-
this._startPointerEvent = null;
|
|
200
|
-
this._cropIfAutoCrop();
|
|
201
|
-
}
|
|
202
|
-
};
|
|
203
|
-
/** Called when the window has lost focus. */
|
|
204
|
-
this._windowBlur = () => {
|
|
205
|
-
// If the window is blurred while dragging we need to stop dragging because the
|
|
206
|
-
// browser won't dispatch the `mouseup` and `touchend` events anymore.
|
|
207
|
-
if (this._lastPointerEvent) {
|
|
208
|
-
this._pointerUp(this._lastPointerEvent);
|
|
209
|
-
}
|
|
210
|
-
};
|
|
211
|
-
this._document = _document;
|
|
212
|
-
viewPortRuler.change()
|
|
213
|
-
.pipe(takeUntil(this._destroy))
|
|
214
|
-
.subscribe(() => this._ngZone.run(() => this.updateCropperPosition()));
|
|
215
|
-
}
|
|
216
|
-
ngOnInit() {
|
|
217
|
-
this._ngZone.runOutsideAngular(() => {
|
|
218
|
-
const element = this._imgContainer.nativeElement;
|
|
219
|
-
element.addEventListener("mousedown", this._pointerDown, activeEventOptions);
|
|
220
|
-
element.addEventListener("touchstart", this._pointerDown, activeEventOptions);
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
ngOnDestroy() {
|
|
224
|
-
this._destroy.next();
|
|
225
|
-
this._destroy.complete();
|
|
226
|
-
const element = this._imgContainer.nativeElement;
|
|
227
|
-
this._lastPointerEvent = null;
|
|
228
|
-
this._removeGlobalEvents();
|
|
229
|
-
element.removeEventListener("mousedown", this._pointerDown, activeEventOptions);
|
|
230
|
-
element.removeEventListener("touchstart", this._pointerDown, activeEventOptions);
|
|
231
|
-
}
|
|
232
|
-
/** Load image with canvas */
|
|
233
|
-
_imgLoaded(imgElement) {
|
|
234
|
-
if (imgElement) {
|
|
235
|
-
this._img = imgElement;
|
|
236
|
-
const canvas = this._imgCanvas.nativeElement;
|
|
237
|
-
canvas.width = imgElement.width;
|
|
238
|
-
canvas.height = imgElement.height;
|
|
239
|
-
const ctx = canvas.getContext("2d");
|
|
240
|
-
ctx.clearRect(0, 0, imgElement.width, imgElement.height);
|
|
241
|
-
ctx.drawImage(imgElement, 0, 0);
|
|
242
|
-
/** set min scale */
|
|
243
|
-
this._updateMinScale(canvas);
|
|
244
|
-
this._updateMaxScale();
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
_setStylesForContImg(values) {
|
|
248
|
-
const newStyles = {};
|
|
249
|
-
if (values.x != null && values.y != null) {
|
|
250
|
-
const rootRect = this._rootRect();
|
|
251
|
-
const x = rootRect.width / 2 - (values.x);
|
|
252
|
-
const y = rootRect.height / 2 - (values.y);
|
|
253
|
-
this._imgRect.x = (values.x);
|
|
254
|
-
this._imgRect.y = (values.y);
|
|
255
|
-
this._imgRect.xc = (x);
|
|
256
|
-
this._imgRect.yc = (y);
|
|
257
|
-
}
|
|
258
|
-
newStyles.transform = `translate3d(${(this._imgRect.x)}px,${(this._imgRect.y)}px, 0)`;
|
|
259
|
-
newStyles.transform += `scale(${this._scal3Fix})`;
|
|
260
|
-
newStyles.transformOrigin = `${this._imgRect.xc}px ${this._imgRect.yc}px 0`;
|
|
261
|
-
newStyles["-webkit-transform"] = newStyles.transform;
|
|
262
|
-
newStyles["-webkit-transform-origin"] = newStyles.transformOrigin;
|
|
263
|
-
for (const key in newStyles) {
|
|
264
|
-
if (newStyles.hasOwnProperty(key)) {
|
|
265
|
-
this._renderer.setStyle(this._imgContainer.nativeElement, key, newStyles[key]);
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
/**
|
|
270
|
-
* Update area and image position only if needed,
|
|
271
|
-
* this is used when window resize
|
|
272
|
-
*/
|
|
273
|
-
updateCropperPosition() {
|
|
274
|
-
if (this.isLoaded) {
|
|
275
|
-
this.updatePosition();
|
|
276
|
-
this._updateAreaIfNeeded();
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
/** Load Image from input event */
|
|
280
|
-
selectInputEvent(img) {
|
|
281
|
-
this._currentInputElement = img.target;
|
|
282
|
-
const _img = img.target;
|
|
283
|
-
if (_img.files && _img.files.length !== 1) {
|
|
284
|
-
return;
|
|
285
|
-
}
|
|
286
|
-
const fileSize = _img.files[0].size;
|
|
287
|
-
const fileName = _img.value.replace(/.*(\/|\\)/, "");
|
|
288
|
-
if (this.maxFileSize && fileSize > this.maxFileSize) {
|
|
289
|
-
const cropEvent = {
|
|
290
|
-
name: fileName,
|
|
291
|
-
type: _img.files[0].type,
|
|
292
|
-
size: fileSize,
|
|
293
|
-
error: ImgCropperError.Size
|
|
294
|
-
};
|
|
295
|
-
this.clean();
|
|
296
|
-
this.error.emit(cropEvent);
|
|
297
|
-
return;
|
|
298
|
-
}
|
|
299
|
-
new Observable(observer => {
|
|
300
|
-
const reader = new FileReader();
|
|
301
|
-
reader.onerror = err => observer.error(err);
|
|
302
|
-
reader.onabort = err => observer.error(err);
|
|
303
|
-
reader.onload = (ev) => setTimeout(() => {
|
|
304
|
-
observer.next(ev);
|
|
305
|
-
observer.complete();
|
|
306
|
-
});
|
|
307
|
-
reader.readAsDataURL(_img.files[0]);
|
|
308
|
-
})
|
|
309
|
-
.pipe(take(1), takeUntil(this._destroy))
|
|
310
|
-
.subscribe((loadEvent) => {
|
|
311
|
-
const originalDataURL = loadEvent.target.result;
|
|
312
|
-
this.loadImage({
|
|
313
|
-
name: fileName,
|
|
314
|
-
size: _img.files[0].size,
|
|
315
|
-
type: this.config.type || _img.files[0].type,
|
|
316
|
-
originalDataURL
|
|
317
|
-
});
|
|
318
|
-
this.cd.markForCheck();
|
|
319
|
-
}, () => {
|
|
320
|
-
const cropEvent = {
|
|
321
|
-
name: fileName,
|
|
322
|
-
size: fileSize,
|
|
323
|
-
error: ImgCropperError.Other,
|
|
324
|
-
errorMsg: "The File could not be loaded.",
|
|
325
|
-
type: _img.files[0].type
|
|
326
|
-
};
|
|
327
|
-
this.clean();
|
|
328
|
-
this.error.emit(cropEvent);
|
|
329
|
-
});
|
|
330
|
-
}
|
|
331
|
-
/** Set the size of the image, the values can be 0 between 1, where 1 is the original size */
|
|
332
|
-
setScale(size, noAutoCrop) {
|
|
333
|
-
// fix min scale
|
|
334
|
-
const newSize = size >= this.minScale && size <= 1 ? size : this.minScale;
|
|
335
|
-
// check
|
|
336
|
-
const changed = size != null && size !== this.scale && newSize !== this.scale;
|
|
337
|
-
this._scale = size;
|
|
338
|
-
if (!changed) {
|
|
339
|
-
return;
|
|
340
|
-
}
|
|
341
|
-
this._scal3Fix = newSize;
|
|
342
|
-
this._updateAbsoluteScale();
|
|
343
|
-
if (this.isLoaded) {
|
|
344
|
-
if (changed) {
|
|
345
|
-
const originPosition = { ...this._imgRect };
|
|
346
|
-
this.offset = {
|
|
347
|
-
x: originPosition.x,
|
|
348
|
-
y: originPosition.y,
|
|
349
|
-
left: originPosition.xc,
|
|
350
|
-
top: originPosition.yc
|
|
351
|
-
};
|
|
352
|
-
this._setStylesForContImg({});
|
|
353
|
-
this._simulatePointerMove();
|
|
354
|
-
}
|
|
355
|
-
else {
|
|
356
|
-
return;
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
else if (this.minScale) {
|
|
360
|
-
this._setStylesForContImg({
|
|
361
|
-
...this._getCenterPoints()
|
|
362
|
-
});
|
|
363
|
-
}
|
|
364
|
-
else {
|
|
365
|
-
return;
|
|
366
|
-
}
|
|
367
|
-
this.scaleChange.emit(size);
|
|
368
|
-
if (!noAutoCrop) {
|
|
369
|
-
this._cropIfAutoCrop();
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
_getCenterPoints() {
|
|
373
|
-
const root = this._elementRef.nativeElement;
|
|
374
|
-
const img = this._imgCanvas.nativeElement;
|
|
375
|
-
const x = (root.offsetWidth - (img.width)) / 2;
|
|
376
|
-
const y = (root.offsetHeight - (img.height)) / 2;
|
|
377
|
-
return {
|
|
378
|
-
x,
|
|
379
|
-
y
|
|
380
|
-
};
|
|
381
|
-
}
|
|
382
|
-
/**
|
|
383
|
-
* Fit to screen
|
|
384
|
-
*/
|
|
385
|
-
fitToScreen() {
|
|
386
|
-
const container = this._elementRef.nativeElement;
|
|
387
|
-
const min = {
|
|
388
|
-
width: container.offsetWidth,
|
|
389
|
-
height: container.offsetHeight
|
|
390
|
-
};
|
|
391
|
-
const { width, height } = this._img;
|
|
392
|
-
const minScale = {
|
|
393
|
-
width: min.width / width,
|
|
394
|
-
height: min.height / height
|
|
395
|
-
};
|
|
396
|
-
const result = Math.max(minScale.width, minScale.height);
|
|
397
|
-
this.setScale(result);
|
|
398
|
-
}
|
|
399
|
-
fit() {
|
|
400
|
-
this.setScale(this.minScale);
|
|
401
|
-
}
|
|
402
|
-
/**
|
|
403
|
-
* Simulate pointerMove with clientX = 0 and clientY = 0,
|
|
404
|
-
* this is used by `setScale` and `rotate`
|
|
405
|
-
*/
|
|
406
|
-
_simulatePointerMove() {
|
|
407
|
-
this._isSliding = true;
|
|
408
|
-
this._startPointerEvent = {
|
|
409
|
-
x: 0,
|
|
410
|
-
y: 0
|
|
411
|
-
};
|
|
412
|
-
this._pointerMove({
|
|
413
|
-
clientX: 0,
|
|
414
|
-
clientY: 0,
|
|
415
|
-
type: "n",
|
|
416
|
-
preventDefault: () => { }
|
|
417
|
-
});
|
|
418
|
-
this._isSliding = false;
|
|
419
|
-
this._startPointerEvent = null;
|
|
420
|
-
}
|
|
421
|
-
_markForCheck() {
|
|
422
|
-
this.cd.markForCheck();
|
|
423
|
-
}
|
|
424
|
-
updatePosition(xOrigin, yOrigin) {
|
|
425
|
-
const hostRect = this._rootRect();
|
|
426
|
-
const areaRect = this._areaCropperRect();
|
|
427
|
-
const areaWidth = areaRect.width > hostRect.width
|
|
428
|
-
? hostRect.width
|
|
429
|
-
: areaRect.width;
|
|
430
|
-
const areaHeight = areaRect.height > hostRect.height
|
|
431
|
-
? hostRect.height
|
|
432
|
-
: areaRect.height;
|
|
433
|
-
let x;
|
|
434
|
-
let y;
|
|
435
|
-
if (xOrigin == null && yOrigin == null) {
|
|
436
|
-
xOrigin = this._imgRect.xc;
|
|
437
|
-
yOrigin = this._imgRect.yc;
|
|
438
|
-
}
|
|
439
|
-
x = (areaRect.left - hostRect.left);
|
|
440
|
-
y = (areaRect.top - hostRect.top);
|
|
441
|
-
x -= (xOrigin - (areaWidth / 2));
|
|
442
|
-
y -= (yOrigin - (areaHeight / 2));
|
|
443
|
-
this._setStylesForContImg({
|
|
444
|
-
x, y
|
|
445
|
-
});
|
|
446
|
-
}
|
|
447
|
-
_slideEnd() {
|
|
448
|
-
this._cropIfAutoCrop();
|
|
449
|
-
}
|
|
450
|
-
_cropIfAutoCrop() {
|
|
451
|
-
if (this.config.autoCrop) {
|
|
452
|
-
this.crop();
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
/** + */
|
|
456
|
-
zoomIn() {
|
|
457
|
-
const scale = this._scal3Fix + .05;
|
|
458
|
-
if (scale > this.minScale && scale <= this._maxScale) {
|
|
459
|
-
this.setScale(scale);
|
|
460
|
-
}
|
|
461
|
-
else {
|
|
462
|
-
this.setScale(this._maxScale);
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
/** Clean the img cropper */
|
|
466
|
-
clean() {
|
|
467
|
-
// fix choosing the same image does not load
|
|
468
|
-
if (this._currentInputElement) {
|
|
469
|
-
this._currentInputElement.value = "";
|
|
470
|
-
this._currentInputElement = null;
|
|
471
|
-
}
|
|
472
|
-
if (this.isLoaded) {
|
|
473
|
-
this._imgRect = {};
|
|
474
|
-
this.offset = undefined;
|
|
475
|
-
this.scale = undefined;
|
|
476
|
-
this._scal3Fix = undefined;
|
|
477
|
-
this._rotation = 0;
|
|
478
|
-
this._minScale = undefined;
|
|
479
|
-
this._isLoadedImg = false;
|
|
480
|
-
this.isLoaded = false;
|
|
481
|
-
this.isCropped = false;
|
|
482
|
-
this._currentLoadConfig = undefined;
|
|
483
|
-
this.config = this._configPrimary;
|
|
484
|
-
const canvas = this._imgCanvas.nativeElement;
|
|
485
|
-
canvas.width = 0;
|
|
486
|
-
canvas.height = 0;
|
|
487
|
-
this.cleaned.emit(null);
|
|
488
|
-
this.cd.markForCheck();
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
/** - */
|
|
492
|
-
zoomOut() {
|
|
493
|
-
const scale = this._scal3Fix - .05;
|
|
494
|
-
if (scale > this.minScale && scale <= this._maxScale) {
|
|
495
|
-
this.setScale(scale);
|
|
496
|
-
}
|
|
497
|
-
else {
|
|
498
|
-
this.fit();
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
center() {
|
|
502
|
-
const newStyles = {
|
|
503
|
-
...this._getCenterPoints()
|
|
504
|
-
};
|
|
505
|
-
this._setStylesForContImg(newStyles);
|
|
506
|
-
this._cropIfAutoCrop();
|
|
507
|
-
}
|
|
508
|
-
/**
|
|
509
|
-
* load an image from a given configuration,
|
|
510
|
-
* or from the result of a cropped image
|
|
511
|
-
*/
|
|
512
|
-
loadImage(config, fn) {
|
|
513
|
-
this.clean();
|
|
514
|
-
const _config = this._currentLoadConfig = typeof config === "string"
|
|
515
|
-
? { originalDataURL: config }
|
|
516
|
-
: { ...config };
|
|
517
|
-
let src = _config.originalDataURL;
|
|
518
|
-
this._primaryAreaWidth = this._configPrimary.width;
|
|
519
|
-
this._primaryAreaHeight = this._configPrimary.height;
|
|
520
|
-
if (_config.areaWidth && _config.areaHeight) {
|
|
521
|
-
this.config.width = _config.areaWidth;
|
|
522
|
-
this.config.height = _config.areaHeight;
|
|
523
|
-
}
|
|
524
|
-
src = normalizeSVG(src);
|
|
525
|
-
const img = createHtmlImg(src);
|
|
526
|
-
const cropEvent = { ..._config };
|
|
527
|
-
new Observable(observer => {
|
|
528
|
-
img.onerror = err => observer.error(err);
|
|
529
|
-
img.onabort = err => observer.error(err);
|
|
530
|
-
img.onload = () => observer.next(null);
|
|
531
|
-
})
|
|
532
|
-
.pipe(take(1), takeUntil(this._destroy))
|
|
533
|
-
.subscribe(() => {
|
|
534
|
-
this._imgLoaded(img);
|
|
535
|
-
this._isLoadedImg = true;
|
|
536
|
-
this.imageLoaded.emit(cropEvent);
|
|
537
|
-
this.cd.markForCheck();
|
|
538
|
-
this._ngZone.runOutsideAngular(() => {
|
|
539
|
-
this._ngZone
|
|
540
|
-
.onStable
|
|
541
|
-
.asObservable()
|
|
542
|
-
.pipe(take(1), takeUntil(this._destroy))
|
|
543
|
-
.subscribe(() => setTimeout(() => this._ngZone.run(() => this._positionImg(cropEvent, fn))));
|
|
544
|
-
});
|
|
545
|
-
}, () => {
|
|
546
|
-
const error = {
|
|
547
|
-
name: _config.name,
|
|
548
|
-
error: ImgCropperError.Type,
|
|
549
|
-
type: _config.type,
|
|
550
|
-
size: _config.size
|
|
551
|
-
};
|
|
552
|
-
this.error.emit(error);
|
|
553
|
-
});
|
|
554
|
-
}
|
|
555
|
-
_updateAreaIfNeeded() {
|
|
556
|
-
if (!this._config.responsiveArea) {
|
|
557
|
-
return;
|
|
558
|
-
}
|
|
559
|
-
const rootRect = this._rootRect();
|
|
560
|
-
const areaRect = this._areaCropperRect();
|
|
561
|
-
const minWidth = this.config.minWidth || 1;
|
|
562
|
-
const minHeight = this.config.minHeight || 1;
|
|
563
|
-
if (!(areaRect.width > rootRect.width
|
|
564
|
-
|| areaRect.height > rootRect.height
|
|
565
|
-
|| areaRect.width < this._primaryAreaWidth
|
|
566
|
-
|| areaRect.height < this._primaryAreaHeight)) {
|
|
567
|
-
return;
|
|
568
|
-
}
|
|
569
|
-
const areaWidthConf = Math.max(this.config.width, minWidth);
|
|
570
|
-
const areaWidthMax = Math.max(rootRect.width, minWidth);
|
|
571
|
-
const minHost = Math.min(Math.max(rootRect.width, minWidth), Math.max(rootRect.height, minHeight));
|
|
572
|
-
const currentScale = this._scal3Fix;
|
|
573
|
-
let newScale = 0;
|
|
574
|
-
const roundConf = this.config.round;
|
|
575
|
-
if (roundConf) {
|
|
576
|
-
this.config.width = this.config.height = minHost;
|
|
577
|
-
}
|
|
578
|
-
else {
|
|
579
|
-
if (areaWidthConf === areaRect.width) {
|
|
580
|
-
if (areaWidthMax > this._primaryAreaWidth) {
|
|
581
|
-
this.config.width = this._primaryAreaWidth;
|
|
582
|
-
this.config.height = (this._primaryAreaWidth * areaRect.height) / areaRect.width;
|
|
583
|
-
newScale = (currentScale * this._primaryAreaWidth) / areaRect.width;
|
|
584
|
-
}
|
|
585
|
-
else {
|
|
586
|
-
this.config.width = areaWidthMax;
|
|
587
|
-
this.config.height = (areaWidthMax * areaRect.height) / areaRect.width;
|
|
588
|
-
newScale = (currentScale * areaWidthMax) / areaRect.width;
|
|
589
|
-
}
|
|
590
|
-
this._updateMinScale();
|
|
591
|
-
this._updateMaxScale();
|
|
592
|
-
this.setScale(newScale, true);
|
|
593
|
-
this._markForCheck();
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
_updateAbsoluteScale() {
|
|
598
|
-
const scale = this._scal3Fix / (this.config.width / this._primaryAreaWidth);
|
|
599
|
-
this._absoluteScale = scale;
|
|
600
|
-
}
|
|
601
|
-
/**
|
|
602
|
-
* Load Image from URL
|
|
603
|
-
* @deprecated Use `loadImage` instead of `setImageUrl`
|
|
604
|
-
* @param src URL
|
|
605
|
-
* @param fn function that will be called before emit the event loaded
|
|
606
|
-
*/
|
|
607
|
-
setImageUrl(src, fn) {
|
|
608
|
-
this.loadImage(src, fn);
|
|
609
|
-
}
|
|
610
|
-
_positionImg(cropEvent, fn) {
|
|
611
|
-
const loadConfig = this._currentLoadConfig;
|
|
612
|
-
this._updateMinScale(this._imgCanvas.nativeElement);
|
|
613
|
-
this._updateMaxScale();
|
|
614
|
-
this.isLoaded = false;
|
|
615
|
-
if (fn) {
|
|
616
|
-
fn();
|
|
617
|
-
}
|
|
618
|
-
else {
|
|
619
|
-
if (loadConfig.scale) {
|
|
620
|
-
this.setScale(loadConfig.scale, true);
|
|
621
|
-
}
|
|
622
|
-
else {
|
|
623
|
-
this.setScale(this.minScale, true);
|
|
624
|
-
}
|
|
625
|
-
this.rotate(loadConfig.rotation || 0);
|
|
626
|
-
this._updateAreaIfNeeded();
|
|
627
|
-
this._markForCheck();
|
|
628
|
-
this._ngZone.runOutsideAngular(() => {
|
|
629
|
-
this._ngZone
|
|
630
|
-
.onStable
|
|
631
|
-
.asObservable()
|
|
632
|
-
.pipe(take(1), takeUntil(this._destroy))
|
|
633
|
-
.subscribe(() => {
|
|
634
|
-
if (loadConfig.xOrigin != null && loadConfig.yOrigin != null) {
|
|
635
|
-
this.updatePosition(loadConfig.xOrigin, loadConfig.yOrigin);
|
|
636
|
-
}
|
|
637
|
-
this._updateAreaIfNeeded();
|
|
638
|
-
this.isLoaded = true;
|
|
639
|
-
this._cropIfAutoCrop();
|
|
640
|
-
this._ngZone.run(() => {
|
|
641
|
-
this._markForCheck();
|
|
642
|
-
this.ready.emit(cropEvent);
|
|
643
|
-
});
|
|
644
|
-
});
|
|
645
|
-
});
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
rotate(degrees) {
|
|
649
|
-
let validDegrees = _normalizeDegrees(degrees);
|
|
650
|
-
// If negative convert to positive
|
|
651
|
-
if (validDegrees < 0) {
|
|
652
|
-
validDegrees += 360;
|
|
653
|
-
}
|
|
654
|
-
const newRotation = _normalizeDegrees((this._rotation || 0) + validDegrees);
|
|
655
|
-
if (newRotation === this._rotation) {
|
|
656
|
-
return;
|
|
657
|
-
}
|
|
658
|
-
const degreesRad = validDegrees * Math.PI / 180;
|
|
659
|
-
const canvas = this._imgCanvas.nativeElement;
|
|
660
|
-
const canvasClon = createCanvasImg(canvas);
|
|
661
|
-
const ctx = canvas.getContext("2d");
|
|
662
|
-
this._rotation = newRotation;
|
|
663
|
-
// clear
|
|
664
|
-
ctx.clearRect(0, 0, canvasClon.width, canvasClon.height);
|
|
665
|
-
// rotate canvas image
|
|
666
|
-
const transform = `rotate(${validDegrees}deg) scale(${1 / this._scal3Fix})`;
|
|
667
|
-
const transformOrigin = `${this._imgRect.xc}px ${this._imgRect.yc}px 0`;
|
|
668
|
-
canvas.style.transform = transform;
|
|
669
|
-
// tslint:disable-next-line: deprecation
|
|
670
|
-
canvas.style.webkitTransform = transform;
|
|
671
|
-
canvas.style.transformOrigin = transformOrigin;
|
|
672
|
-
// tslint:disable-next-line: deprecation
|
|
673
|
-
canvas.style.webkitTransformOrigin = transformOrigin;
|
|
674
|
-
const { left, top } = canvas.getBoundingClientRect();
|
|
675
|
-
// save rect
|
|
676
|
-
const canvasRect = canvas.getBoundingClientRect();
|
|
677
|
-
// remove rotate styles
|
|
678
|
-
canvas.removeAttribute("style");
|
|
679
|
-
// set w & h
|
|
680
|
-
const w = canvasRect.width;
|
|
681
|
-
const h = canvasRect.height;
|
|
682
|
-
ctx.canvas.width = w;
|
|
683
|
-
ctx.canvas.height = h;
|
|
684
|
-
// clear
|
|
685
|
-
ctx.clearRect(0, 0, w, h);
|
|
686
|
-
// translate and rotate
|
|
687
|
-
ctx.translate(w / 2, h / 2);
|
|
688
|
-
ctx.rotate(degreesRad);
|
|
689
|
-
ctx.drawImage(canvasClon, -canvasClon.width / 2, -canvasClon.height / 2);
|
|
690
|
-
// Update min scale
|
|
691
|
-
this._updateMinScale(canvas);
|
|
692
|
-
this._updateMaxScale();
|
|
693
|
-
// set the minimum scale, only if necessary
|
|
694
|
-
if (this.scale < this.minScale) {
|
|
695
|
-
this.setScale(0, true);
|
|
696
|
-
} // ↑ no AutoCrop
|
|
697
|
-
const rootRect = this._rootRect();
|
|
698
|
-
this._setStylesForContImg({
|
|
699
|
-
x: (left - rootRect.left),
|
|
700
|
-
y: (top - rootRect.top)
|
|
701
|
-
});
|
|
702
|
-
// keep image inside the frame
|
|
703
|
-
const originPosition = { ...this._imgRect };
|
|
704
|
-
this.offset = {
|
|
705
|
-
x: originPosition.x,
|
|
706
|
-
y: originPosition.y,
|
|
707
|
-
left: originPosition.xc,
|
|
708
|
-
top: originPosition.yc
|
|
709
|
-
};
|
|
710
|
-
this._setStylesForContImg({});
|
|
711
|
-
this._simulatePointerMove();
|
|
712
|
-
this._cropIfAutoCrop();
|
|
713
|
-
}
|
|
714
|
-
_updateMinScale(canvas) {
|
|
715
|
-
if (!canvas) {
|
|
716
|
-
canvas = this._imgCanvas.nativeElement;
|
|
717
|
-
}
|
|
718
|
-
const config = this.config;
|
|
719
|
-
const minScale = (config.extraZoomOut ? Math.min : Math.max)(config.width / canvas.width, config.height / canvas.height);
|
|
720
|
-
this._minScale = minScale;
|
|
721
|
-
this.minScaleChange.emit(minScale);
|
|
722
|
-
}
|
|
723
|
-
_updateMaxScale() {
|
|
724
|
-
const maxScale = (this.config.width / this._primaryAreaWidth);
|
|
725
|
-
this._maxScale = maxScale;
|
|
726
|
-
this.maxScaleChange.emit(maxScale);
|
|
727
|
-
}
|
|
728
|
-
/**
|
|
729
|
-
* Resize & crop image
|
|
730
|
-
*/
|
|
731
|
-
crop(config) {
|
|
732
|
-
const newConfig = config
|
|
733
|
-
? mergeDeep({}, this.config || new ImgCropperConfig(), config) : this.config;
|
|
734
|
-
const cropEvent = this._imgCrop(newConfig);
|
|
735
|
-
this.cd.markForCheck();
|
|
736
|
-
return cropEvent;
|
|
737
|
-
}
|
|
738
|
-
/**
|
|
739
|
-
* @docs-private
|
|
740
|
-
*/
|
|
741
|
-
_imgCrop(myConfig) {
|
|
742
|
-
const canvasElement = document.createElement("canvas");
|
|
743
|
-
const areaRect = this._areaCropperRect();
|
|
744
|
-
const canvasRect = this._canvasRect();
|
|
745
|
-
const scaleFix = this._scal3Fix;
|
|
746
|
-
const left = (areaRect.left - canvasRect.left) / scaleFix;
|
|
747
|
-
const top = (areaRect.top - canvasRect.top) / scaleFix;
|
|
748
|
-
const { output } = myConfig;
|
|
749
|
-
const currentImageLoadConfig = this._currentLoadConfig;
|
|
750
|
-
const area = {
|
|
751
|
-
width: myConfig.width,
|
|
752
|
-
height: myConfig.height
|
|
753
|
-
};
|
|
754
|
-
canvasElement.width = area.width / scaleFix;
|
|
755
|
-
canvasElement.height = area.height / scaleFix;
|
|
756
|
-
const ctx = canvasElement.getContext("2d");
|
|
757
|
-
if (myConfig.fill) {
|
|
758
|
-
ctx.fillStyle = myConfig.fill;
|
|
759
|
-
ctx.fillRect(0, 0, canvasElement.width, canvasElement.height);
|
|
760
|
-
}
|
|
761
|
-
ctx.drawImage(this._imgCanvas.nativeElement, -(left), -(top));
|
|
762
|
-
const result = canvasElement;
|
|
763
|
-
if (myConfig.output === ImgResolution.Default) {
|
|
764
|
-
resizeCanvas(result, this._configPrimary.width, this._configPrimary.height);
|
|
765
|
-
}
|
|
766
|
-
else if (typeof output === "object") {
|
|
767
|
-
if (output.width && output.height) {
|
|
768
|
-
resizeCanvas(result, output.width, output.height);
|
|
769
|
-
}
|
|
770
|
-
else if (output.width) {
|
|
771
|
-
const newHeight = area.height * output.width / area.width;
|
|
772
|
-
resizeCanvas(result, output.width, newHeight);
|
|
773
|
-
}
|
|
774
|
-
else if (output.height) {
|
|
775
|
-
const newWidth = area.width * output.height / area.height;
|
|
776
|
-
resizeCanvas(result, newWidth, output.height);
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
const type = currentImageLoadConfig.originalDataURL.startsWith("http")
|
|
780
|
-
? currentImageLoadConfig.type || myConfig.type
|
|
781
|
-
: myConfig.type || currentImageLoadConfig.type;
|
|
782
|
-
const dataURL = result.toDataURL(type);
|
|
783
|
-
const cropEvent = {
|
|
784
|
-
dataURL,
|
|
785
|
-
type,
|
|
786
|
-
name: currentImageLoadConfig.name,
|
|
787
|
-
areaWidth: this._primaryAreaWidth,
|
|
788
|
-
areaHeight: this._primaryAreaHeight,
|
|
789
|
-
width: result.width,
|
|
790
|
-
height: result.height,
|
|
791
|
-
originalDataURL: currentImageLoadConfig.originalDataURL,
|
|
792
|
-
scale: this._absoluteScale,
|
|
793
|
-
rotation: this._rotation,
|
|
794
|
-
left: (areaRect.left - canvasRect.left) / this._scal3Fix,
|
|
795
|
-
top: (areaRect.top - canvasRect.top) / this._scal3Fix,
|
|
796
|
-
size: currentImageLoadConfig.size,
|
|
797
|
-
xOrigin: this._imgRect.xc,
|
|
798
|
-
yOrigin: this._imgRect.yc,
|
|
799
|
-
position: {
|
|
800
|
-
x: this._imgRect.xc,
|
|
801
|
-
y: this._imgRect.yc
|
|
802
|
-
}
|
|
803
|
-
};
|
|
804
|
-
this.isCropped = true;
|
|
805
|
-
this.cropped.emit(cropEvent);
|
|
806
|
-
return cropEvent;
|
|
807
|
-
}
|
|
808
|
-
_rootRect() {
|
|
809
|
-
return this._elementRef.nativeElement.getBoundingClientRect();
|
|
810
|
-
}
|
|
811
|
-
_areaCropperRect() {
|
|
812
|
-
return this._areaRef.nativeElement.getBoundingClientRect();
|
|
813
|
-
}
|
|
814
|
-
_canvasRect() {
|
|
815
|
-
return this._imgCanvas.nativeElement.getBoundingClientRect();
|
|
816
|
-
}
|
|
817
|
-
_bindGlobalEvents(triggerEvent) {
|
|
818
|
-
const element = this._document;
|
|
819
|
-
const isTouch = isTouchEvent(triggerEvent);
|
|
820
|
-
const moveEventName = isTouch ? "touchmove" : "mousemove";
|
|
821
|
-
const endEventName = isTouch ? "touchend" : "mouseup";
|
|
822
|
-
element.addEventListener(moveEventName, this._pointerMove, activeEventOptions);
|
|
823
|
-
element.addEventListener(endEventName, this._pointerUp, activeEventOptions);
|
|
824
|
-
if (isTouch) {
|
|
825
|
-
element.addEventListener("touchcancel", this._pointerUp, activeEventOptions);
|
|
826
|
-
}
|
|
827
|
-
const window = this._getWindow();
|
|
828
|
-
if (typeof window !== "undefined" && window) {
|
|
829
|
-
window.addEventListener("blur", this._windowBlur);
|
|
830
|
-
}
|
|
831
|
-
}
|
|
832
|
-
/** Removes any global event listeners that we may have added. */
|
|
833
|
-
_removeGlobalEvents() {
|
|
834
|
-
const element = this._document;
|
|
835
|
-
element.removeEventListener("mousemove", this._pointerMove, activeEventOptions);
|
|
836
|
-
element.removeEventListener("mouseup", this._pointerUp, activeEventOptions);
|
|
837
|
-
element.removeEventListener("touchmove", this._pointerMove, activeEventOptions);
|
|
838
|
-
element.removeEventListener("touchend", this._pointerUp, activeEventOptions);
|
|
839
|
-
element.removeEventListener("touchcancel", this._pointerUp, activeEventOptions);
|
|
840
|
-
const window = this._getWindow();
|
|
841
|
-
if (typeof window !== "undefined" && window) {
|
|
842
|
-
window.removeEventListener("blur", this._windowBlur);
|
|
843
|
-
}
|
|
844
|
-
}
|
|
845
|
-
/** Use defaultView of injected document if available or fallback to global window reference */
|
|
846
|
-
_getWindow() {
|
|
847
|
-
return this._document.defaultView || window;
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
|
-
NiceImageCropperComponent.и = "NiceImageCropper";
|
|
851
|
-
NiceImageCropperComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: NiceImageCropperComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: DOCUMENT }, { token: i1.ViewportRuler }], target: i0.ɵɵFactoryTarget.Component });
|
|
852
|
-
NiceImageCropperComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: NiceImageCropperComponent, selector: "nice-img-cropper, nice-image-cropper", inputs: { config: "config", scale: "scale", maxFileSize: "maxFileSize" }, outputs: { scaleChange: "scaleChange", minScaleChange: "minScale", maxScaleChange: "maxScale", imageLoaded: "imageLoaded", ready: "ready", cropped: "cropped", cleaned: "cleaned", error: "error" }, viewQueries: [{ propertyName: "_imgContainer", first: true, predicate: ["_imgContainer"], descendants: true, static: true }, { propertyName: "_areaRef", first: true, predicate: ["_area"], descendants: true, read: ElementRef }, { propertyName: "_imgCanvas", first: true, predicate: ["_imgCanvas"], descendants: true, static: true }], ngImport: i0, template: "<!-- (selectstart): On Safari starting to slide temporarily triggers text selection mode which\nshow the wrong cursor. We prevent it by stopping the `selectstart` event. -->\n<div class=\"image-container\" #_imgContainer\n (selectstart)=\"$event.preventDefault()\"\n>\n <canvas #_imgCanvas></canvas>\n</div>\n<nice-cropper-area\n #_area\n *ngIf=\"_isLoadedImg\"\n [round]=\"!!config.round\"\n [resizableArea]=\"!!config.resizableArea\"\n [keepAspectRatio]=\"!!config.keepAspectRatio\"\n [ngStyle]=\"{\n width: config.width + 'px',\n height: config.height + 'px'\n }\"\n></nice-cropper-area>\n<button class=\"close-button\" mat-icon-button *ngIf=\"_isLoadedImg\" (click)=\"clean()\">\n <mat-icon>arrow_back</mat-icon>\n</button>\n", styles: ["nice-image-cropper,nice-img-cropper{-webkit-user-select:none;user-select:none;display:flex;overflow:hidden;position:relative;justify-content:center;align-items:center}nice-image-cropper .image-container,nice-img-cropper .image-container{cursor:move;position:absolute;top:0;left:0;display:flex;touch-action:none}nice-image-cropper .image-container>canvas,nice-img-cropper .image-container>canvas{display:block}nice-image-cropper .close-button,nice-img-cropper .close-button{position:absolute;top:8px;left:8px;background-color:#fff!important;border-radius:4px;height:20px;width:20px;min-height:20px}nice-image-cropper .close-button .mat-icon,nice-img-cropper .close-button .mat-icon{height:14px!important;width:14px!important;font-size:14px!important;line-height:14px!important}\n"], dependencies: [{ kind: "directive", type: i0.forwardRef(function () { return i2.NgIf; }), selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i0.forwardRef(function () { return i2.NgStyle; }), selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i0.forwardRef(function () { return i3.MatIconButton; }), selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i0.forwardRef(function () { return i4.MatIcon; }), selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i0.forwardRef(function () { return NiceCropperAreaComponent; }), selector: "nice-cropper-area", inputs: ["keepAspectRatio", "round", "resizableArea"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
853
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: NiceImageCropperComponent, decorators: [{
|
|
854
|
-
type: Component,
|
|
855
|
-
args: [{ changeDetection: ChangeDetectionStrategy.OnPush, preserveWhitespaces: false, selector: "nice-img-cropper, nice-image-cropper", encapsulation: ViewEncapsulation.None, template: "<!-- (selectstart): On Safari starting to slide temporarily triggers text selection mode which\nshow the wrong cursor. We prevent it by stopping the `selectstart` event. -->\n<div class=\"image-container\" #_imgContainer\n (selectstart)=\"$event.preventDefault()\"\n>\n <canvas #_imgCanvas></canvas>\n</div>\n<nice-cropper-area\n #_area\n *ngIf=\"_isLoadedImg\"\n [round]=\"!!config.round\"\n [resizableArea]=\"!!config.resizableArea\"\n [keepAspectRatio]=\"!!config.keepAspectRatio\"\n [ngStyle]=\"{\n width: config.width + 'px',\n height: config.height + 'px'\n }\"\n></nice-cropper-area>\n<button class=\"close-button\" mat-icon-button *ngIf=\"_isLoadedImg\" (click)=\"clean()\">\n <mat-icon>arrow_back</mat-icon>\n</button>\n", styles: ["nice-image-cropper,nice-img-cropper{-webkit-user-select:none;user-select:none;display:flex;overflow:hidden;position:relative;justify-content:center;align-items:center}nice-image-cropper .image-container,nice-img-cropper .image-container{cursor:move;position:absolute;top:0;left:0;display:flex;touch-action:none}nice-image-cropper .image-container>canvas,nice-img-cropper .image-container>canvas{display:block}nice-image-cropper .close-button,nice-img-cropper .close-button{position:absolute;top:8px;left:8px;background-color:#fff!important;border-radius:4px;height:20px;width:20px;min-height:20px}nice-image-cropper .close-button .mat-icon,nice-img-cropper .close-button .mat-icon{height:14px!important;width:14px!important;font-size:14px!important;line-height:14px!important}\n"] }]
|
|
856
|
-
}], ctorParameters: function () { return [{ type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: undefined, decorators: [{
|
|
857
|
-
type: Inject,
|
|
858
|
-
args: [DOCUMENT]
|
|
859
|
-
}] }, { type: i1.ViewportRuler }]; }, propDecorators: { _imgContainer: [{
|
|
860
|
-
type: ViewChild,
|
|
861
|
-
args: ["_imgContainer", { static: true }]
|
|
862
|
-
}], _areaRef: [{
|
|
863
|
-
type: ViewChild,
|
|
864
|
-
args: ["_area", { read: ElementRef }]
|
|
865
|
-
}], _imgCanvas: [{
|
|
866
|
-
type: ViewChild,
|
|
867
|
-
args: ["_imgCanvas", { static: true }]
|
|
868
|
-
}], config: [{
|
|
869
|
-
type: Input
|
|
870
|
-
}], scale: [{
|
|
871
|
-
type: Input
|
|
872
|
-
}], maxFileSize: [{
|
|
873
|
-
type: Input
|
|
874
|
-
}], scaleChange: [{
|
|
875
|
-
type: Output
|
|
876
|
-
}], minScaleChange: [{
|
|
877
|
-
type: Output,
|
|
878
|
-
args: ["minScale"]
|
|
879
|
-
}], maxScaleChange: [{
|
|
880
|
-
type: Output,
|
|
881
|
-
args: ["maxScale"]
|
|
882
|
-
}], imageLoaded: [{
|
|
883
|
-
type: Output
|
|
884
|
-
}], ready: [{
|
|
885
|
-
type: Output
|
|
886
|
-
}], cropped: [{
|
|
887
|
-
type: Output
|
|
888
|
-
}], cleaned: [{
|
|
889
|
-
type: Output
|
|
890
|
-
}], error: [{
|
|
891
|
-
type: Output
|
|
892
|
-
}] } });
|
|
893
|
-
/**
|
|
894
|
-
* Normalize degrees for cropper rotation
|
|
895
|
-
* @docs-private
|
|
896
|
-
*/
|
|
897
|
-
export function _normalizeDegrees(n) {
|
|
898
|
-
const de = n % 360;
|
|
899
|
-
if (de % 90) {
|
|
900
|
-
throw new Error(`LyCropper: Invalid \`${n}\` degree, only accepted values: 0, 90, 180, 270 & 360.`);
|
|
901
|
-
}
|
|
902
|
-
return de;
|
|
903
|
-
}
|
|
904
|
-
/**
|
|
905
|
-
* @docs-private
|
|
906
|
-
*/
|
|
907
|
-
function createCanvasImg(img) {
|
|
908
|
-
// create a new canvas
|
|
909
|
-
const newCanvas = document.createElement("canvas");
|
|
910
|
-
const context = newCanvas.getContext("2d");
|
|
911
|
-
// set dimensions
|
|
912
|
-
newCanvas.width = img.width;
|
|
913
|
-
newCanvas.height = img.height;
|
|
914
|
-
// apply the old canvas to the new one
|
|
915
|
-
context.drawImage(img, 0, 0);
|
|
916
|
-
// return the new canvas
|
|
917
|
-
return newCanvas;
|
|
918
|
-
}
|
|
919
|
-
const DATA_IMAGE_SVG_PREFIX = "data:image/svg+xml;base64,";
|
|
920
|
-
function normalizeSVG(dataURL) {
|
|
921
|
-
if (window.atob && isSvgImage(dataURL)) {
|
|
922
|
-
const len = dataURL.length / 5;
|
|
923
|
-
const text = window.atob(dataURL.replace(DATA_IMAGE_SVG_PREFIX, ""));
|
|
924
|
-
const span = document.createElement("span");
|
|
925
|
-
span.innerHTML = text;
|
|
926
|
-
const svg = span.querySelector("svg");
|
|
927
|
-
span.setAttribute("style", "display:none");
|
|
928
|
-
document.body.appendChild(span);
|
|
929
|
-
const width = parseFloat(getComputedStyle(svg).width) || 1;
|
|
930
|
-
const height = parseFloat(getComputedStyle(svg).height) || 1;
|
|
931
|
-
const max = Math.max(width, height);
|
|
932
|
-
svg.setAttribute("width", `${len / (width / max)}px`);
|
|
933
|
-
svg.setAttribute("height", `${len / (height / max)}px`);
|
|
934
|
-
const result = DATA_IMAGE_SVG_PREFIX + window.btoa(span.innerHTML);
|
|
935
|
-
document.body.removeChild(span);
|
|
936
|
-
return result;
|
|
937
|
-
}
|
|
938
|
-
return dataURL;
|
|
939
|
-
}
|
|
940
|
-
function isSvgImage(dataUrl) {
|
|
941
|
-
return dataUrl.startsWith(DATA_IMAGE_SVG_PREFIX);
|
|
942
|
-
}
|
|
943
|
-
function createHtmlImg(src) {
|
|
944
|
-
const img = new Image();
|
|
945
|
-
img.crossOrigin = "anonymous";
|
|
946
|
-
img.src = src;
|
|
947
|
-
return img;
|
|
948
|
-
}
|
|
949
|
-
function getGesturePointFromEvent(event) {
|
|
950
|
-
// `touches` will be empty for start/end events so we have to fall back to `changedTouches`.
|
|
951
|
-
const point = isTouchEvent(event)
|
|
952
|
-
? (event.touches[0] || event.changedTouches[0])
|
|
953
|
-
: event;
|
|
954
|
-
return {
|
|
955
|
-
x: point.clientX,
|
|
956
|
-
y: point.clientY
|
|
957
|
-
};
|
|
958
|
-
}
|
|
959
|
-
/** Returns whether an event is a touch event. */
|
|
960
|
-
function isTouchEvent(event) {
|
|
961
|
-
return event.type[0] === "t";
|
|
962
|
-
}
|
|
963
|
-
export function round(n) {
|
|
964
|
-
return Math.round(n);
|
|
965
|
-
}
|
|
966
|
-
/**
|
|
967
|
-
* Simple object check.
|
|
968
|
-
* @param item
|
|
969
|
-
*/
|
|
970
|
-
function isObject(item) {
|
|
971
|
-
return (item && typeof item === "object" && !Array.isArray(item));
|
|
972
|
-
}
|
|
973
|
-
/**
|
|
974
|
-
* Deep merge two objects.
|
|
975
|
-
* @param target
|
|
976
|
-
* @param ...sources
|
|
977
|
-
*/
|
|
978
|
-
export function mergeDeep(target, ...sources) {
|
|
979
|
-
if (!sources.length) {
|
|
980
|
-
return target;
|
|
981
|
-
}
|
|
982
|
-
const source = sources.shift();
|
|
983
|
-
if (isObject(target) && isObject(source)) {
|
|
984
|
-
for (const key in source) {
|
|
985
|
-
if (isObject(source[key])) {
|
|
986
|
-
if (!target[key]) {
|
|
987
|
-
Object.assign(target, { [key]: {} });
|
|
988
|
-
}
|
|
989
|
-
mergeDeep(target[key], source[key]);
|
|
990
|
-
}
|
|
991
|
-
else {
|
|
992
|
-
Object.assign(target, { [key]: source[key] });
|
|
993
|
-
}
|
|
994
|
-
}
|
|
995
|
-
}
|
|
996
|
-
return mergeDeep(target, ...sources);
|
|
997
|
-
}
|
|
998
|
-
/**
|
|
999
|
-
* We have the cropper area in the same file to fix the build
|
|
1000
|
-
*/
|
|
1001
|
-
export class NiceCropperAreaComponent {
|
|
1002
|
-
constructor(_document, _elementRef, _cropper, _ngZone) {
|
|
1003
|
-
this._elementRef = _elementRef;
|
|
1004
|
-
this._cropper = _cropper;
|
|
1005
|
-
this._ngZone = _ngZone;
|
|
1006
|
-
this._pointerDown = (event) => {
|
|
1007
|
-
// Don't do anything if the
|
|
1008
|
-
// user is using anything other than the main mouse button.
|
|
1009
|
-
if (this._isSliding || (!isTouchEvent(event) && event.button !== 0)) {
|
|
1010
|
-
return;
|
|
1011
|
-
}
|
|
1012
|
-
event.preventDefault();
|
|
1013
|
-
this._ngZone.run(() => {
|
|
1014
|
-
this._isSliding = true;
|
|
1015
|
-
this._lastPointerEvent = event;
|
|
1016
|
-
this._startPointerEvent = getGesturePointFromEvent(event);
|
|
1017
|
-
this._startAreaRect = this._cropper._areaCropperRect();
|
|
1018
|
-
this._startImgRect = this._cropper._canvasRect();
|
|
1019
|
-
event.preventDefault();
|
|
1020
|
-
this._bindGlobalEvents(event);
|
|
1021
|
-
});
|
|
1022
|
-
};
|
|
1023
|
-
this._pointerMove = (event) => {
|
|
1024
|
-
if (this._isSliding) {
|
|
1025
|
-
event.preventDefault();
|
|
1026
|
-
this._lastPointerEvent = event;
|
|
1027
|
-
const element = this._elementRef.nativeElement;
|
|
1028
|
-
const { width, height, minWidth, minHeight } = this._cropper.config;
|
|
1029
|
-
const point = getGesturePointFromEvent(event);
|
|
1030
|
-
const deltaX = point.x - this._startPointerEvent.x;
|
|
1031
|
-
const deltaY = point.y - this._startPointerEvent.y;
|
|
1032
|
-
const startAreaRect = this._startAreaRect;
|
|
1033
|
-
const startImgRect = this._startImgRect;
|
|
1034
|
-
const isRound = this.round;
|
|
1035
|
-
const keepAspectRatio = this._cropper.config.keepAspectRatio || event.shiftKey;
|
|
1036
|
-
let newWidth = 0;
|
|
1037
|
-
let newHeight = 0;
|
|
1038
|
-
const rootRect = this._cropper._rootRect();
|
|
1039
|
-
if (isRound) {
|
|
1040
|
-
// The distance from the center of the cropper area to the pointer
|
|
1041
|
-
const originX = ((width / 2 / Math.sqrt(2)) + deltaX);
|
|
1042
|
-
const originY = ((height / 2 / Math.sqrt(2)) + deltaY);
|
|
1043
|
-
// Leg
|
|
1044
|
-
const side = Math.sqrt(originX ** 2 + originY ** 2);
|
|
1045
|
-
newWidth = newHeight = side * 2;
|
|
1046
|
-
}
|
|
1047
|
-
else if (keepAspectRatio) {
|
|
1048
|
-
newWidth = width + deltaX * 2;
|
|
1049
|
-
newHeight = height + deltaY * 2;
|
|
1050
|
-
if (width !== height) {
|
|
1051
|
-
if (width > height) {
|
|
1052
|
-
newHeight = height / (width / newWidth);
|
|
1053
|
-
}
|
|
1054
|
-
else if (height > width) {
|
|
1055
|
-
newWidth = width / (height / newHeight);
|
|
1056
|
-
}
|
|
1057
|
-
}
|
|
1058
|
-
else {
|
|
1059
|
-
newWidth = newHeight = Math.max(newWidth, newHeight);
|
|
1060
|
-
}
|
|
1061
|
-
}
|
|
1062
|
-
else {
|
|
1063
|
-
newWidth = width + deltaX * 2;
|
|
1064
|
-
newHeight = height + deltaY * 2;
|
|
1065
|
-
}
|
|
1066
|
-
// To min width
|
|
1067
|
-
if (newWidth < minWidth) {
|
|
1068
|
-
newWidth = minWidth;
|
|
1069
|
-
}
|
|
1070
|
-
// To min height
|
|
1071
|
-
if (newHeight < minHeight) {
|
|
1072
|
-
newHeight = minHeight;
|
|
1073
|
-
}
|
|
1074
|
-
// Do not overflow the cropper area
|
|
1075
|
-
const centerX = startAreaRect.x + startAreaRect.width / 2;
|
|
1076
|
-
const centerY = startAreaRect.y + startAreaRect.height / 2;
|
|
1077
|
-
const topOverflow = startImgRect.y > centerY - (newHeight / 2);
|
|
1078
|
-
const bottomOverflow = centerY + (newHeight / 2) > startImgRect.bottom;
|
|
1079
|
-
const minHeightOnOverflow = Math.min((centerY - startImgRect.y) * 2, (startImgRect.bottom - centerY) * 2);
|
|
1080
|
-
const leftOverflow = startImgRect.x > centerX - (newWidth / 2);
|
|
1081
|
-
const rightOverflow = centerX + (newWidth / 2) > startImgRect.right;
|
|
1082
|
-
const minWidthOnOverflow = Math.min((centerX - startImgRect.x) * 2, (startImgRect.right - centerX) * 2);
|
|
1083
|
-
const minOnOverflow = Math.min(minWidthOnOverflow, minHeightOnOverflow);
|
|
1084
|
-
if (round) {
|
|
1085
|
-
if (topOverflow || bottomOverflow || leftOverflow || rightOverflow) {
|
|
1086
|
-
newHeight = newWidth = minOnOverflow;
|
|
1087
|
-
}
|
|
1088
|
-
}
|
|
1089
|
-
else if (keepAspectRatio) {
|
|
1090
|
-
const newNewWidth = [];
|
|
1091
|
-
const newNewHeight = [];
|
|
1092
|
-
if ((topOverflow || bottomOverflow) && Math.min()) {
|
|
1093
|
-
newHeight = minHeightOnOverflow;
|
|
1094
|
-
newNewHeight.push(newHeight);
|
|
1095
|
-
newWidth = width / (height / minHeightOnOverflow);
|
|
1096
|
-
newNewWidth.push(newWidth);
|
|
1097
|
-
}
|
|
1098
|
-
if ((leftOverflow || rightOverflow)) {
|
|
1099
|
-
newWidth = minWidthOnOverflow;
|
|
1100
|
-
newNewWidth.push(newWidth);
|
|
1101
|
-
newHeight = height / (width / minWidthOnOverflow);
|
|
1102
|
-
newNewHeight.push(newHeight);
|
|
1103
|
-
}
|
|
1104
|
-
if (newNewWidth.length === 2) {
|
|
1105
|
-
newWidth = Math.min(...newNewWidth);
|
|
1106
|
-
}
|
|
1107
|
-
if (newNewHeight.length === 2) {
|
|
1108
|
-
newHeight = Math.min(...newNewHeight);
|
|
1109
|
-
}
|
|
1110
|
-
}
|
|
1111
|
-
else {
|
|
1112
|
-
if (topOverflow || bottomOverflow) {
|
|
1113
|
-
newHeight = minHeightOnOverflow;
|
|
1114
|
-
}
|
|
1115
|
-
if (leftOverflow || rightOverflow) {
|
|
1116
|
-
newWidth = minWidthOnOverflow;
|
|
1117
|
-
}
|
|
1118
|
-
}
|
|
1119
|
-
// Do not overflow the container
|
|
1120
|
-
if (round) {
|
|
1121
|
-
const min = Math.min(rootRect.width, rootRect.height);
|
|
1122
|
-
if (newWidth > min) {
|
|
1123
|
-
newWidth = newHeight = min;
|
|
1124
|
-
}
|
|
1125
|
-
else if (newHeight > min) {
|
|
1126
|
-
newWidth = newHeight = min;
|
|
1127
|
-
}
|
|
1128
|
-
}
|
|
1129
|
-
else if (keepAspectRatio) {
|
|
1130
|
-
if (newWidth > rootRect.width) {
|
|
1131
|
-
newWidth = rootRect.width;
|
|
1132
|
-
newHeight = height / (width / rootRect.width);
|
|
1133
|
-
}
|
|
1134
|
-
else if (newHeight > rootRect.height) {
|
|
1135
|
-
newWidth = width / (height / rootRect.height);
|
|
1136
|
-
newHeight = rootRect.height;
|
|
1137
|
-
}
|
|
1138
|
-
}
|
|
1139
|
-
else {
|
|
1140
|
-
if (newWidth > rootRect.width) {
|
|
1141
|
-
newWidth = rootRect.width;
|
|
1142
|
-
}
|
|
1143
|
-
else if (newHeight > rootRect.height) {
|
|
1144
|
-
newHeight = rootRect.height;
|
|
1145
|
-
}
|
|
1146
|
-
}
|
|
1147
|
-
// round values
|
|
1148
|
-
newWidth = Math.round(newWidth);
|
|
1149
|
-
newHeight = Math.round(newHeight);
|
|
1150
|
-
element.style.width = `${newWidth}px`;
|
|
1151
|
-
element.style.height = `${newHeight}px`;
|
|
1152
|
-
this._currentWidth = newWidth;
|
|
1153
|
-
this._currentHeight = newHeight;
|
|
1154
|
-
}
|
|
1155
|
-
};
|
|
1156
|
-
/** Called when the user has lifted their pointer. */
|
|
1157
|
-
this._pointerUp = (event) => {
|
|
1158
|
-
if (this._isSliding) {
|
|
1159
|
-
event.preventDefault();
|
|
1160
|
-
this._removeGlobalEvents();
|
|
1161
|
-
this._cropper._primaryAreaWidth = this._cropper.config.width = this._currentWidth;
|
|
1162
|
-
this._cropper._primaryAreaHeight = this._cropper.config.height = this._currentHeight;
|
|
1163
|
-
this._cropper.config = this._cropper.config;
|
|
1164
|
-
this._cropper._updateMinScale();
|
|
1165
|
-
this._isSliding = false;
|
|
1166
|
-
this._startPointerEvent = null;
|
|
1167
|
-
}
|
|
1168
|
-
};
|
|
1169
|
-
/** Called when the window has lost focus. */
|
|
1170
|
-
this._windowBlur = () => {
|
|
1171
|
-
// If the window is blurred while dragging we need to stop dragging because the
|
|
1172
|
-
// browser won't dispatch the `mouseup` and `touchend` events anymore.
|
|
1173
|
-
if (this._lastPointerEvent) {
|
|
1174
|
-
this._pointerUp(this._lastPointerEvent);
|
|
1175
|
-
}
|
|
1176
|
-
};
|
|
1177
|
-
this._document = _document;
|
|
1178
|
-
}
|
|
1179
|
-
set resizableArea(val) {
|
|
1180
|
-
if (val !== this._resizableArea) {
|
|
1181
|
-
this._resizableArea = val;
|
|
1182
|
-
Promise.resolve(null).then(() => {
|
|
1183
|
-
if (val) {
|
|
1184
|
-
this._removeResizableArea();
|
|
1185
|
-
this._addResizableArea();
|
|
1186
|
-
}
|
|
1187
|
-
else {
|
|
1188
|
-
this._removeResizableArea();
|
|
1189
|
-
}
|
|
1190
|
-
});
|
|
1191
|
-
}
|
|
1192
|
-
}
|
|
1193
|
-
get resizableArea() {
|
|
1194
|
-
return this._resizableArea;
|
|
1195
|
-
}
|
|
1196
|
-
ngOnDestroy() {
|
|
1197
|
-
this._removeResizableArea();
|
|
1198
|
-
}
|
|
1199
|
-
_addResizableArea() {
|
|
1200
|
-
this._ngZone.runOutsideAngular(() => {
|
|
1201
|
-
const element = this._resizer.nativeElement;
|
|
1202
|
-
element.addEventListener("mousedown", this._pointerDown, activeEventOptions);
|
|
1203
|
-
element.addEventListener("touchstart", this._pointerDown, activeEventOptions);
|
|
1204
|
-
});
|
|
1205
|
-
}
|
|
1206
|
-
_removeResizableArea() {
|
|
1207
|
-
const element = this._resizer?.nativeElement;
|
|
1208
|
-
if (element) {
|
|
1209
|
-
this._lastPointerEvent = null;
|
|
1210
|
-
this._removeGlobalEvents();
|
|
1211
|
-
element.removeEventListener("mousedown", this._pointerDown, activeEventOptions);
|
|
1212
|
-
element.removeEventListener("touchstart", this._pointerDown, activeEventOptions);
|
|
1213
|
-
}
|
|
1214
|
-
}
|
|
1215
|
-
_bindGlobalEvents(triggerEvent) {
|
|
1216
|
-
const element = this._document;
|
|
1217
|
-
const isTouch = isTouchEvent(triggerEvent);
|
|
1218
|
-
const moveEventName = isTouch ? "touchmove" : "mousemove";
|
|
1219
|
-
const endEventName = isTouch ? "touchend" : "mouseup";
|
|
1220
|
-
element.addEventListener(moveEventName, this._pointerMove, activeEventOptions);
|
|
1221
|
-
element.addEventListener(endEventName, this._pointerUp, activeEventOptions);
|
|
1222
|
-
if (isTouch) {
|
|
1223
|
-
element.addEventListener("touchcancel", this._pointerUp, activeEventOptions);
|
|
1224
|
-
}
|
|
1225
|
-
const window = this._getWindow();
|
|
1226
|
-
if (typeof window !== "undefined" && window) {
|
|
1227
|
-
window.addEventListener("blur", this._windowBlur);
|
|
1228
|
-
}
|
|
1229
|
-
}
|
|
1230
|
-
/** Removes any global event listeners that we may have added. */
|
|
1231
|
-
_removeGlobalEvents() {
|
|
1232
|
-
const element = this._document;
|
|
1233
|
-
element.removeEventListener("mousemove", this._pointerMove, activeEventOptions);
|
|
1234
|
-
element.removeEventListener("mouseup", this._pointerUp, activeEventOptions);
|
|
1235
|
-
element.removeEventListener("touchmove", this._pointerMove, activeEventOptions);
|
|
1236
|
-
element.removeEventListener("touchend", this._pointerUp, activeEventOptions);
|
|
1237
|
-
element.removeEventListener("touchcancel", this._pointerUp, activeEventOptions);
|
|
1238
|
-
const window = this._getWindow();
|
|
1239
|
-
if (typeof window !== "undefined" && window) {
|
|
1240
|
-
window.removeEventListener("blur", this._windowBlur);
|
|
1241
|
-
}
|
|
1242
|
-
}
|
|
1243
|
-
/** Use defaultView of injected document if available or fallback to global window reference */
|
|
1244
|
-
_getWindow() {
|
|
1245
|
-
return this._document.defaultView || window;
|
|
1246
|
-
}
|
|
1247
|
-
}
|
|
1248
|
-
NiceCropperAreaComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: NiceCropperAreaComponent, deps: [{ token: DOCUMENT }, { token: i0.ElementRef }, { token: NiceImageCropperComponent }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
|
|
1249
|
-
NiceCropperAreaComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: NiceCropperAreaComponent, selector: "nice-cropper-area", inputs: { keepAspectRatio: "keepAspectRatio", round: "round", resizableArea: "resizableArea" }, host: { properties: { "class.round": "this.round" } }, viewQueries: [{ propertyName: "_resizer", first: true, predicate: ["resizer"], descendants: true }], ngImport: i0, template: "<div class=\"resizer\" #resizer *ngIf=\"resizableArea\"></div>\n", styles: ["nice-cropper-area{pointer-events:none;box-shadow:0 0 0 20000px #0006;margin:auto;position:absolute;inset:0}nice-cropper-area.round{border-radius:50%}nice-cropper-area:before,nice-cropper-area:after{position:absolute;inset:0;content:\"\"}nice-cropper-area:before{width:0;height:0;margin:auto;border-radius:50%;background:#fff;border:solid 2px rgb(255,255,255)}nice-cropper-area:after{border:solid 2px rgb(255,255,255);border-radius:inherit}nice-cropper-area .resizer{width:10px;height:10px;background:#fff;border-radius:3px;position:absolute;touch-action:none;bottom:0;pointer-events:all}nice-cropper-area .resizer:before{content:\"\";width:20px;height:20px;transform:translate(-25%,-25%)}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1250
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: NiceCropperAreaComponent, decorators: [{
|
|
1251
|
-
type: Component,
|
|
1252
|
-
args: [{ selector: "nice-cropper-area", encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"resizer\" #resizer *ngIf=\"resizableArea\"></div>\n", styles: ["nice-cropper-area{pointer-events:none;box-shadow:0 0 0 20000px #0006;margin:auto;position:absolute;inset:0}nice-cropper-area.round{border-radius:50%}nice-cropper-area:before,nice-cropper-area:after{position:absolute;inset:0;content:\"\"}nice-cropper-area:before{width:0;height:0;margin:auto;border-radius:50%;background:#fff;border:solid 2px rgb(255,255,255)}nice-cropper-area:after{border:solid 2px rgb(255,255,255);border-radius:inherit}nice-cropper-area .resizer{width:10px;height:10px;background:#fff;border-radius:3px;position:absolute;touch-action:none;bottom:0;pointer-events:all}nice-cropper-area .resizer:before{content:\"\";width:20px;height:20px;transform:translate(-25%,-25%)}\n"] }]
|
|
1253
|
-
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
1254
|
-
type: Inject,
|
|
1255
|
-
args: [DOCUMENT]
|
|
1256
|
-
}] }, { type: i0.ElementRef }, { type: NiceImageCropperComponent }, { type: i0.NgZone }]; }, propDecorators: { _resizer: [{
|
|
1257
|
-
type: ViewChild,
|
|
1258
|
-
args: ["resizer"]
|
|
1259
|
-
}], keepAspectRatio: [{
|
|
1260
|
-
type: Input
|
|
1261
|
-
}], round: [{
|
|
1262
|
-
type: Input
|
|
1263
|
-
}, {
|
|
1264
|
-
type: HostBinding,
|
|
1265
|
-
args: ["class.round"]
|
|
1266
|
-
}], resizableArea: [{
|
|
1267
|
-
type: Input
|
|
1268
|
-
}] } });
|
|
1269
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1hZ2UtY3JvcHBlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uaWNlLXVpLWtpdC12Mi9zcmMvbGliL2NvbXBvbmVudHMvaW1hZ2UtY3JvcHBlci9pbWFnZS1jcm9wcGVyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25pY2UtdWkta2l0LXYyL3NyYy9saWIvY29tcG9uZW50cy9pbWFnZS1jcm9wcGVyL2ltYWdlLWNyb3BwZXIudGVtcGxhdGUuaHRtbCIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25pY2UtdWkta2l0LXYyL3NyYy9saWIvY29tcG9uZW50cy9pbWFnZS1jcm9wcGVyL2ltYWdlLWNyb3BwZXItYXJlYS50ZW1wbGF0ZS5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsT0FBTyxFQUFFLCtCQUErQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDeEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEVBQ0gsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFBRSxXQUFXLEVBQ3pCLE1BQU0sRUFDTixLQUFLLEVBQ0wsTUFBTSxFQUdOLE1BQU0sRUFDTixTQUFTLEVBQ1QsU0FBUyxFQUNULGlCQUFpQixFQUNwQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMzQyxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQzs7Ozs7O0FBRS9DLE1BQU0sa0JBQWtC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QUMsbUJBQW1CLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztTQUN4RDtJQUNMLENBQUM7SUFFRCwrRkFBK0Y7SUFDdkYsVUFBVTtRQUNkLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLElBQUksTUFBTSxDQUFDO0lBQ2hELENBQUM7O3FIQWxTUSx3QkFBd0Isa0JBMkJyQixRQUFRO3lHQTNCWCx3QkFBd0IscVRFN3pDckMsa0VBQ0E7MkZGNHpDYSx3QkFBd0I7a0JBUHBDLFNBQVM7K0JBQ0ksbUJBQW1CLGlCQUdkLGlCQUFpQixDQUFDLElBQUksbUJBQ3BCLHVCQUF1QixDQUFDLE1BQU07OzBCQTZCMUMsTUFBTTsyQkFBQyxRQUFROytIQXpCSCxRQUFRO3NCQUR4QixTQUFTO3VCQUFDLFNBQVM7Z0JBSWIsZUFBZTtzQkFEckIsS0FBSztnQkFLQyxLQUFLO3NCQUZYLEtBQUs7O3NCQUNMLFdBQVc7dUJBQUMsYUFBYTtnQkE4QmYsYUFBYTtzQkFEdkIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQWRhcHRlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9BLWwteS1sLWUvQWx5bGUtVUkvdHJlZS8xMC41LjMvc3JjL2xpYi9pbWFnZS1jcm9wcGVyXG4gKi9cblxuaW1wb3J0IHsgbm9ybWFsaXplUGFzc2l2ZUxpc3RlbmVyT3B0aW9ucyB9IGZyb20gXCJAYW5ndWxhci9jZGsvcGxhdGZvcm1cIjtcbmltcG9ydCB7IFZpZXdwb3J0UnVsZXIgfSBmcm9tIFwiQGFuZ3VsYXIvY2RrL3Njcm9sbGluZ1wiO1xuaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uXCI7XG5pbXBvcnQge1xuICAgIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICAgIENoYW5nZURldGVjdG9yUmVmLFxuICAgIENvbXBvbmVudCxcbiAgICBFbGVtZW50UmVmLFxuICAgIEV2ZW50RW1pdHRlciwgSG9zdEJpbmRpbmcsXG4gICAgSW5qZWN0LFxuICAgIElucHV0LFxuICAgIE5nWm9uZSxcbiAgICBPbkRlc3Ryb3ksXG4gICAgT25Jbml0LFxuICAgIE91dHB1dCxcbiAgICBSZW5kZXJlcjIsXG4gICAgVmlld0NoaWxkLFxuICAgIFZpZXdFbmNhcHN1bGF0aW9uXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0IH0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7IHRha2UsIHRha2VVbnRpbCB9IGZyb20gXCJyeGpzL29wZXJhdG9yc1wiO1xuaW1wb3J0IHsgcmVzaXplQ2FudmFzIH0gZnJvbSBcIi4vcmVzaXplLWNhbnZhc1wiO1xuXG5jb25zdCBhY3RpdmVFdmVudE9wdGlvbnMgPSBub3JtYWxpemVQYXNzaXZlTGlzdGVuZXJPcHRpb25zKHsgcGFzc2l2ZTogZmFsc2UgfSk7XG5cbi8qKiBJbWFnZSBDcm9wcGVyIENvbmZpZyAqL1xuZXhwb3J0IGNsYXNzIEltZ0Nyb3BwZXJDb25maWcge1xuICAgIC8qKiBDcm9wcGVyIGFyZWEgd2lkdGggKi9cbiAgICB3aWR0aCA9IDI1MDtcbiAgICAvKiogQ3JvcHBlciBhcmVhIGhlaWdodCAqL1xuICAgIGhlaWdodCA9IDIwMDtcbiAgICBtaW5XaWR0aCA9IDQwO1xuICAgIG1pbkhlaWdodCA9IDQwO1xuICAgIC8qKiBJZiB0aGlzIGlzIG5vdCBkZWZpbmVkLCB0aGUgbmV3IGltYWdlIHdpbGwgYmUgYXV0b21hdGljYWxseSBkZWZpbmVkLiAqL1xuICAgIHR5cGU/OiBzdHJpbmc7XG4gICAgLyoqIEJhY2tncm91bmQgY29sb3IoIGRlZmF1bHQ6IG51bGwpLCBpZiBpcyBudWxsIGluIHBuZyBpcyB0cmFuc3BhcmVudCBidXQgbm90IGluIGpwZy4gKi9cbiAgICBmaWxsPzogc3RyaW5nIHwgbnVsbDtcbiAgICAvKipcbiAgICAgKiBTZXQgYW50aS1hbGlhc2VkIChkZWZhdWx0OiB0cnVlKVxuICAgICAqIEBkZXByZWNhdGVkIHRoaXMgaXMgbm90IG5lY2Vzc2FyeSBhcyB0aGUgY3JvcHBlciB3aWxsIGF1dG9tYXRpY2FsbHkgcmVzaXplIHRoZSBpbWFnZVxuICAgICAqIHRvIHRoZSBiZXN0IHF1YWxpdHlcbiAgICAgKi9cbiAgICBhbnRpQWxpYXNlZCA9IHRydWU7XG4gICAgYXV0b0Nyb3A/OiBib29sZWFuO1xuICAgIG91dHB1dD86IEltZ091dHB1dCB8IEltZ1Jlc29sdXRpb24gPSBJbWdSZXNvbHV0aW9uLkRlZmF1bHQ7XG4gICAgLyoqXG4gICAgICogWm9vbSBvdXQgdW50aWwgdGhlIGVudGlyZSBpbWFnZSBmaXRzIGludG8gdGhlIGNyb3BwaW5nIGFyZWEuXG4gICAgICogZGVmYXVsdDogZmFsc2VcbiAgICAgKi9cbiAgICBleHRyYVpvb21PdXQ/OiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIEVtaXQgZXZlbnQgYGVycm9yYCBpZiB0aGUgZmlsZSBzaXplIGluIGJ5dGVzIGZvciB0aGUgbGltaXQuXG4gICAgICogTm90ZTogSXQgb25seSB3b3JrcyB3aGVuIHRoZSBpbWFnZSBpcyByZWNlaXZlZCBmcm9tIHRoZSBgPGlucHV0PmAgZXZlbnQuXG4gICAgICovXG4gICAgbWF4RmlsZVNpemU/OiBudW1iZXIgfCBudWxsO1xuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIGNyb3BwZXIgYXJlYSB3aWxsIGJlIHJvdW5kLlxuICAgICAqIFRoaXMgaW1wbGllcyB0aGF0IHRoZSBjcm9wcGVyIGFyZWEgd2lsbCBtYWludGFpbiBpdHMgYXNwZWN0IHJhdGlvLlxuICAgICAqIGRlZmF1bHQ6IGZhbHNlXG4gICAgICovXG4gICAgcm91bmQ/OiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIGNyb3BwZXIgYXJlYSBpcyByZXNpemFibGUuXG4gICAgICogZGVmYXVsdDogZmFsc2VcbiAgICAgKi9cbiAgICByZXNpemFibGVBcmVhPzogYm9vbGVhbjtcbiAgICAvKipcbiAgICAgKiBLZWVwIHRoZSB3aWR0aCBhbmQgaGVpZ2h0IG9mIHRoZSBncm93aW5nIGFyZWEgdGhlIHNhbWUgYWNjb3JkaW5nXG4gICAgICogdG8gYEltZ0Nyb3BwZXJDb25maWcud2lkdGhgIGFuZCBgSW1nQ3JvcHBlckNvbmZpZy5oZWlnaHRgXG4gICAgICogZGVmYXVsdDogZmFsc2VcbiAgICAgKi9cbiAgICBrZWVwQXNwZWN0UmF0aW8/OiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIGNyb3BwZXIgYXJlYSBpcyByZXNwb25zaXZlLlxuICAgICAqIEJ5IGRlZmF1bHQsIHRoZSB3aWR0aCBhbmQgaGVpZ2h0IG9mIHRoZSBjcm9wcGVyIGFyZWEgaXMgZml4ZWQsXG4gICAgICogc28gY2FuIHVzZSB3aGVuIHRoZSBjcm9wcGVyIGFyZWEgaXMgbGFyZ2VyIHRoYW4gaXRzIGNvbnRhaW5lcixcbiAgICAgKiBvdGhlcndpc2UgdGhpcyB3aWxsIGJyaW5nIHByb2JsZW1zIHdoZW4gY3JvcHBpbmcuXG4gICAgICovXG4gICAgcmVzcG9uc2l2ZUFyZWE/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIFRoZSBvdXRwdXQgaW1hZ2VcbiAqIFdpdGggdGhpcyBvcHRpb24geW91IGNhbiByZXNpemUgdGhlIG91dHB1dCBpbWFnZS5cbiAqIElmIGB3aWR0aGAgb3IgYGhlaWdodGAgYXJlIDAsIHRoaXMgd2lsbCBiZSBzZXQgYXV0b21hdGljYWxseS5cbiAqIEJvdGggY2Fubm90IGJlIDAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSW1nT3V0cHV0IHtcbiAgICAvKipcbiAgICAgKiBUaGUgY3JvcHBlZCBpbWFnZSB3aWxsIGJlIHJlc2l6ZWQgdG8gdGhpcyBgd2lkdGhgLlxuICAgICAqL1xuICAgIHdpZHRoOiBudW1iZXI7XG4gICAgLyoqXG4gICAgICogQ3JvcHBlZCBpbWFnZSB3aWxsIGJlIHJlc2l6ZWQgdG8gdGhpcyBgaGVpZ2h0YC5cbiAgICAgKi9cbiAgICBoZWlnaHQ6IG51bWJlcjtcbn1cblxuLyoqIEltYWdlIG91dHB1dCAqL1xuZXhwb3J0IGVudW0gSW1nUmVzb2x1dGlvbiB7XG4gICAgLyoqXG4gICAgICogVGhlIG91dHB1dCBpbWFnZSB3aWxsIGJlIGVxdWFsIHRvIHRoZSBpbml0aWFsIHNpemUgb2YgdGhlIGNyb3BwZXIgYXJlYS5cbiAgICAgKi9cbiAgICBEZWZhdWx0LFxuICAgIC8qKiBKdXN0IGNyb3AgdGhlIGltYWdlIHdpdGhvdXQgcmVzaXppbmcgKi9cbiAgICBPcmlnaW5hbEltYWdlXG59XG5cbi8qKiBJbWFnZSBvdXRwdXQgKi9cbmV4cG9ydCBlbnVtIEltZ0Nyb3BwZXJFcnJvciB7XG4gICAgLyoqIFRoZSBsb2FkZWQgaW1hZ2UgZXhjZWVkcyB0aGUgc2l6ZSBsaW1pdCBzZXQuICovXG4gICAgU2l6ZSxcbiAgICAvKiogVGhlIGZpbGUgbG9hZGVkIGlzIG5vdCBpbWFnZS4gKi9cbiAgICBUeXBlLFxuICAgIC8qKiBXaGVuIHRoZSBpbWFnZSBoYXMgbm90IGJlZW4gbG9hZGVkLiAqL1xuICAgIE90aGVyXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW1nQ3JvcHBlckV2ZW50IHtcbiAgICAvKiogQ3JvcHBlZCBpbWFnZSBkYXRhIFVSTCAqL1xuICAgIGRhdGFVUkw/OiBzdHJpbmc7XG4gICAgbmFtZTogc3RyaW5nIHwgbnVsbDtcbiAgICAvKiogRmlsZXR5cGUgKi9cbiAgICB0eXBlPzogc3RyaW5nO1xuICAgIC8qKiBDcm9wcGVkIGFyZWEgd2lkdGggKi9cbiAgICBhcmVhV2lkdGg6IG51bWJlcjtcbiAgICAvKiogQ3JvcHBlZCBhcmVhIGhlaWdodCAqL1xuICAgIGFyZWFIZWlnaHQ6IG51bWJlcjtcbiAgICAvKiogQ3JvcHBlZCBpbWFnZSB3aWR0aCAqL1xuICAgIHdpZHRoOiBudW1iZXI7XG4gICAgLyoqIENyb3BwZWQgaW1hZ2UgaGVpZ2h0ICovXG4gICAgaGVpZ2h0OiBudW1iZXI7XG4gICAgLyoqIE9yaWdpbmFsIEltYWdlIGRhdGEgVVJMICovXG4gICAgb3JpZ2luYWxEYXRhVVJMPzogc3RyaW5nO1xuICAgIHNjYWxlOiBudW1iZXI7XG4gICAgLyoqIEN1cnJlbnQgcm90YXRpb24gaW4gZGVncmVlcyAqL1xuICAgIHJvdGF0aW9uOiBudW1iZXI7XG4gICAgLyoqIFNpemUgb2YgdGhlIGltYWdlIGluIGJ5dGVzICovXG4gICAgc2l6ZTogbnVtYmVyO1xuICAgIC8qKiBTY2FsZWQgb2Zmc2V0IGZyb20gdGhlIGxlZnQgZWRnZSBvZiB0aGUgaW1hZ2UgKi9cbiAgICBsZWZ0OiBudW1iZXI7XG4gICAgLyoqIFNjYWxlZCBvZmZzZXQgZnJvbSB0aGUgdG9wIGVkZ2Ugb2YgdGhlIGltYWdlICovXG4gICAgdG9wOiBudW1iZXI7XG4gICAgLyoqXG4gICAgICogU2NhbGVkIG9mZnNldCBmcm9tIHRoZSBsZWZ0IGVkZ2Ugb2YgdGhlIGltYWdlIHRvIGNlbnRlciBvZiBhcmVhXG4gICAgICogQ2FuIGJlIHVzZWQgdG8gc2V0IGltYWdlIHBvc2l0aW9uXG4gICAgICovXG4gICAgeE9yaWdpbjogbnVtYmVyO1xuICAgIC8qKlxuICAgICAqIFNjYWxlZCBvZmZzZXQgZnJvbSB0aGUgdG9wIGVkZ2Ugb2YgdGhlIGltYWdlIHRvIGNlbnRlciBvZiBhcmVhXG4gICAgICogQ2FuIGJlIHVzZWQgdG8gc2V0IGltYWdlIHBvc2l0aW9uXG4gICAgICovXG4gICAgeU9yaWdpbjogbnVtYmVyO1xuICAgIC8qKiBAZGVwcmVjYXRlZCBVc2UgYHhPcmlnaW4gJiB5T3JpZ2luYCBpbnN0ZWFkLiAqL1xuICAgIHBvc2l0aW9uPzoge1xuICAgICAgICB4OiBudW1iZXJcbiAgICAgICAgeTogbnVtYmVyXG4gICAgfTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJbWdDcm9wcGVyRXJyb3JFdmVudCB7XG4gICAgbmFtZT86IHN0cmluZztcbiAgICAvKiogU2l6ZSBvZiB0aGUgaW1hZ2UgaW4gYnl0ZXMgKi9cbiAgICBzaXplOiBudW1iZXI7XG4gICAgLyoqIEZpbGV0eXBlICovXG4gICAgdHlwZTogc3RyaW5nO1xuICAgIC8qKiBUeXBlIG9mIGVycm9yICovXG4gICAgZXJyb3I6IEltZ0Nyb3BwZXJFcnJvcjtcbiAgICBlcnJvck1zZz86IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIEltZ1JlY3Qge1xuICAgIHg6IG51bWJlcjtcbiAgICB5OiBudW1iZXI7XG4gICAgeGM6IG51bWJlcjtcbiAgICB5YzogbnVtYmVyO1xuICAgIC8qKiB0cmFuc2Zvcm0gd2l0aCAqL1xuICAgIHd0OiBudW1iZXI7XG4gICAgaHQ6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJbWdDcm9wcGVyTG9hZGVyQ29uZmlnIHtcbiAgICBuYW1lPzogc3RyaW5nIHwgbnVsbDtcbiAgICAvKiogRmlsZXR5cGUgKi9cbiAgICB0eXBlPzogc3RyaW5nO1xuICAgIC8qKiBDcm9wcGVkIGFyZWEgd2lkdGggKi9cbiAgICBhcmVhV2lkdGg/OiBudW1iZXI7XG4gICAgLyoqIENyb3BwZWQgYXJlYSBoZWlnaHQgKi9cbiAgICBhcmVhSGVpZ2h0PzogbnVtYmVyO1xuICAgIC8qKiBDcm9wcGVkIGltYWdlIHdpZHRoICovXG4gICAgd2lkdGg/OiBudW1iZXI7XG4gICAgLyoqIENyb3BwZWQgaW1hZ2UgaGVpZ2h0ICovXG4gICAgaGVpZ2h0PzogbnVtYmVyO1xuICAgIC8qKiBPcmlnaW5hbCBJbWFnZSBkYXRhIFVSTCAqL1xuICAgIG9yaWdpbmFsRGF0YVVSTDogc3RyaW5nO1xuICAgIHNjYWxlPzogbnVtYmVyO1xuICAgIC8qKiBDdXJyZW50IHJvdGF0aW9uIGluIGRlZ3JlZXMgKi9cbiAgICByb3RhdGlvbj86IG51bWJlcjtcbiAgICAvKiogU2l6ZSBvZiB0aGUgaW1hZ2UgaW4gYnl0ZXMgKi9cbiAgICBzaXplPzogbnVtYmVyO1xuICAgIC8qKiBPZmZzZXQgZnJvbSB0aGUgbGVmdCBlZGdlIG9mIHRoZSBpbWFnZSB0byBjZW50ZXIgb2YgYXJlYSAqL1xuICAgIHhPcmlnaW4/OiBudW1iZXI7XG4gICAgLyoqIE9mZnNldCBmcm9tIHRoZSB0b3AgZWRnZSBvZiB0aGUgaW1hZ2UgdG8gY2VudGVyIG9mIGFyZWEgKi9cbiAgICB5T3JpZ2luPzogbnVtYmVyO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgICBwcmVzZXJ2ZVdoaXRlc3BhY2VzOiBmYWxzZSxcbiAgICBzZWxlY3RvcjogXCJuaWNlLWltZy1jcm9wcGVyLCBuaWNlLWltYWdlLWNyb3BwZXJcIixcbiAgICB0ZW1wbGF0ZVVybDogXCJpbWFnZS1jcm9wcGVyLnRlbXBsYXRlLmh0bWxcIixcbiAgICBzdHlsZVVybHM6IFtcImltYWdlLWNyb3BwZXIuc3R5bGUuc2Nzc1wiXSxcbiAgICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lXG59KVxuZXhwb3J0IGNsYXNzIE5pY2VJbWFnZUNyb3BwZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gICAgc3RhdGljIHJlYWRvbmx5INC4ID0gXCJOaWNlSW1hZ2VDcm9wcGVyXCI7XG5cbiAgICBwcml2YXRlIF9jdXJyZW50TG9hZENvbmZpZz86IEltZ0Nyb3BwZXJMb2FkZXJDb25maWc7XG5cbiAgICAvKiogT3JpZ2luYWwgaW1hZ2UgKi9cbiAgICBwcml2YXRlIF9pbWc6IEhUTUxJbWFnZUVsZW1lbnQ7XG4gICAgcHJpdmF0ZSBvZmZzZXQ/OiB7XG4gICAgICAgIHg6IG51bWJlclxuICAgICAgICB5OiBudW1iZXJcbiAgICAgICAgbGVmdDogbnVtYmVyXG4gICAgICAgIHRvcDogbnVtYmVyXG4gICAgfTtcbiAgICBwcml2YXRlIF9zY2FsZT86IG51bWJlcjtcbiAgICBwcml2YXRlIF9zY2FsM0ZpeD86IG51bWJlcjtcbiAgICBwcml2YXRlIF9taW5TY2FsZT86IG51bWJlcjtcbiAgICBwcml2YXRlIF9tYXhTY2FsZT86IG51bWJlcjtcbiAgICAvKiogSW5pdGlhbCBjb25maWcgKi9cbiAgICBwcml2YXRlIF9jb25maWdQcmltYXJ5OiBJbWdDcm9wcGVyQ29uZmlnO1xuICAgIHByaXZhdGUgX2NvbmZpZzogSW1nQ3JvcHBlckNvbmZpZztcbiAgICBwcml2YXRlIF9pbWdSZWN0OiBJbWdSZWN0ID0ge30gYXMgYW55O1xuICAgIHByaXZhdGUgX3JvdGF0aW9uID0gMDtcbiAgICAvLyBwcml2YXRlIF9zaXplSW5CeXRlczogbnVtYmVyIHwgbnVsbDtcbiAgICBwcml2YXRlIF9pc1NsaWRpbmc6IGJvb2xlYW47XG4gICAgLyoqIEtlZXBzIHRyYWNrIG9mIHRoZSBsYXN0IHBvaW50ZXIgZXZlbnQgdGhhdCB3YXMgY2FwdHVyZWQgYnkgdGhlIGNyb3AgYXJlYS4gKi9cbiAgICBwcml2YXRlIF9sYXN0UG9pbnRlckV2ZW50OiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCB8IG51bGw7XG4gICAgcHJpdmF0ZSBfc3RhcnRQb2ludGVyRXZlbnQ6IHtcbiAgICAgICAgeDogbnVtYmVyXG4gICAgICAgIHk6IG51bWJlclxuICAgIH0gfCBudWxsO1xuICAgIHB1YmxpYyBfcHJpbWFyeUFyZWFXaWR0aDogbnVtYmVyO1xuICAgIHB1YmxpYyBfcHJpbWFyeUFyZWFIZWlnaHQ6IG51bWJlcjtcblxuICAgIHB1YmxpYyBfYWJzb2x1dGVTY2FsZTogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogV2hlbiBpcyBsb2FkZWQgaW1hZ2VcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgX2lzTG9hZGVkSW1nOiBib29sZWFuO1xuXG4gICAgLyoqIFdoZW4gaXMgbG9hZGVkIGltYWdlICYgcmVhZHkgZm9yIGNyb3AgKi9cbiAgICBwdWJsaWMgaXNMb2FkZWQ6IGJvb2xlYW47XG4gICAgLyoqIFdoZW4gdGhlIGNyb3BwZXIgaXMgcmVhZHkgdG8gYmUgaW50ZXJhY3RlZCAgKi9cbiAgICBwdWJsaWMgaXNSZWFkeTogYm9vbGVhbjtcbiAgICBwdWJsaWMgaXNDcm9wcGVkOiBib29sZWFuO1xuXG4gICAgQFZpZXdDaGlsZChcIl9pbWdDb250YWluZXJcIiwgeyBzdGF0aWM6IHRydWUgfSlcbiAgICBwcml2YXRlIF9pbWdDb250YWluZXI6IEVsZW1lbnRSZWY7XG5cbiAgICBAVmlld0NoaWxkKFwiX2FyZWFcIiwgeyByZWFkOiBFbGVtZW50UmVmIH0pXG4gICAgcHJpdmF0ZSBfYXJlYVJlZjogRWxlbWVudFJlZjtcbiAgICBAVmlld0NoaWxkKFwiX2ltZ0NhbnZhc1wiLCB7IHN0YXRpYzogdHJ1ZSB9KVxuICAgIHByaXZhdGUgX2ltZ0NhbnZhczogRWxlbWVudFJlZjxIVE1MQ2FudmFzRWxlbWVudD47XG5cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBzZXQgY29uZmlnKHZhbDogSW1nQ3JvcHBlckNvbmZpZykge1xuICAgICAgICB0aGlzLl9jb25maWcgPSBtZXJnZURlZXAoe30sIG5ldyBJbWdDcm9wcGVyQ29uZmlnKCksIHZhbCk7XG4gICAgICAgIHRoaXMuX2NvbmZpZ1ByaW1hcnkgPSBtZXJnZURlZXAoe30sIHRoaXMuX2NvbmZpZyk7XG4gICAgICAgIHRoaXMuX3ByaW1hcnlBcmVhV2lkdGggPSB0aGlzLmNvbmZpZy53aWR0aDtcbiAgICAgICAgdGhpcy5fcHJpbWFyeUFyZWFIZWlnaHQgPSB0aGlzLmNvbmZpZy5oZWlnaHQ7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHRoaXMuX2NvbmZpZy5yb3VuZFxuICAgICAgICAgICAgJiYgdGhpcy5jb25maWcud2lkdGggIT09IHRoaXMuY29uZmlnLmhlaWdodFxuICAgICAgICApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtOaWNlSW1hZ2VDcm9wcGVyQ29tcG9uZW50LtC4fTogQm90aCB3aWR0aCBhbmQgaGVpZ2h0IG11c3QgYmUgZXF1YWwgd2hlbiB1c2luZyBcXGBJbWdDcm9wcGVyQ29uZmlnLnJvdW5kID0gdHJ1ZVxcYGApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG1heEZpbGVTaXplID0gdGhpcy5fY29uZmlnLm1heEZpbGVTaXplO1xuICAgICAgICBpZiAobWF4RmlsZVNpemUpIHtcbiAgICAgICAgICAgIHRoaXMubWF4RmlsZVNpemUgPSBtYXhGaWxlU2l6ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBwdWJsaWMgZ2V0IGNvbmZpZygpOiBJbWdDcm9wcGVyQ29uZmlnIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbmZpZztcbiAgICB9XG4gICAgLyoqIFNldCBzY2FsZSAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHNldCBzY2FsZSh2YWw6IG51bWJlciB8IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLnNldFNjYWxlKHZhbCk7XG4gICAgfVxuICAgIHB1YmxpYyBnZXQgc2NhbGUoKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NjYWxlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEVtaXQgZXZlbnQgYGVycm9yYCBpZiB0aGUgZmlsZSBzaXplIGZvciB0aGUgbGltaXQuXG4gICAgICogTm90ZTogSXQgb25seSB3b3JrcyB3aGVuIHRoZSBpbWFnZSBpcyByZWNlaXZlZCBmcm9tIHRoZSBgPGlucHV0PmAgZXZlbnQuXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgbWF4RmlsZVNpemU6IG51bWJlcjtcblxuICAgIC8qKiBHZXQgbWluIHNjYWxlICovXG4gICAgcHVibGljIGdldCBtaW5TY2FsZSgpOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWluU2NhbGU7XG4gICAgfVxuXG4gICAgQE91dHB1dCgpXG4gICAgcHJpdmF0ZSByZWFkb25seSBzY2FsZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuXG4gICAgLyoqIEVtaXRzIG1pbmltdW0gc3VwcG9ydGVkIGltYWdlIHNjYWxlICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLW91dHB1dC1yZW5hbWVcbiAgICBAT3V0cHV0KFwibWluU2NhbGVcIilcbiAgICBwcml2YXRlIHJlYWRvbmx5IG1pblNjYWxlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG5cbiAgICAvKiogRW1pdHMgbWF4aW11bSBzdXBwb3J0ZWQgaW1hZ2Ugc2NhbGUgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tb3V0cHV0LXJlbmFtZVxuICAgIEBPdXRwdXQoXCJtYXhTY2FsZVwiKVxuICAgIHByaXZhdGUgcmVhZG9ubHkgbWF4U2NhbGVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcblxuICAgIC8qKiBFbWl0cyB3aGVuIHRoZSBpbWFnZSBpcyBsb2FkZWQgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwcml2YXRlIHJlYWRvbmx5IGltYWdlTG9hZGVkID0gbmV3IEV2ZW50RW1pdHRlcjxJbWdDcm9wcGVyRXZlbnQ+KCk7XG5cbiAgICAvKiogRW1pdHMgd2hlbiB0aGUgY3JvcHBlciBpcyByZWFkeSB0byBiZSBpbnRlcmFjdGVkICovXG4gICAgQE91dHB1dCgpXG4gICAgcHJpdmF0ZSByZWFkb25seSByZWFkeSA9IG5ldyBFdmVudEVtaXR0ZXI8SW1nQ3JvcHBlckV2ZW50PigpO1xuXG4gICAgLyoqIE9uIGNyb3AgbmV3IGltYWdlICovXG4gICAgQE91dHB1dCgpXG4gICAgcHJpdmF0ZSByZWFkb25seSBjcm9wcGVkID0gbmV3IEV2ZW50RW1pdHRlcjxJbWdDcm9wcGVyRXZlbnQ+KCk7XG5cbiAgICAvKiogRW1pdHMgd2hlbiB0aGUgY3JvcHBlciBpcyBjbGVhbmVkICovXG4gICAgQE91dHB1dCgpXG4gICAgcHJpdmF0ZSByZWFkb25seSBjbGVhbmVkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gICAgLyoqIEVtaXQgYW4gZXJyb3Igd2hlbiB0aGUgbG9hZGVkIGltYWdlIGlzIG5vdCB2YWxpZCAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogbm8tb3V0cHV0LW5hdGl2ZVxuICAgIEBPdXRwdXQoKVxuICAgIHByaXZhdGUgcmVhZG9ubHkgZXJyb3IgPSBuZXcgRXZlbnRFbWl0dGVyPEltZ0Nyb3BwZXJFcnJvckV2ZW50PigpO1xuXG4gICAgcHJpdmF0ZSBfY3VycmVudElucHV0RWxlbWVudD86IEhUTUxJbnB1dEVsZW1lbnQ7XG5cbiAgICAvKiogRW1pdHMgd2hlbmV2ZXIgdGhlIGNvbXBvbmVudCBpcyBkZXN0cm95ZWQuICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBfZGVzdHJveSA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgICAvKiogVXNlZCB0byBzdWJzY3JpYmUgdG8gZ2xvYmFsIG1vdmUgYW5kIGVuZCBldmVudHMgKi9cbiAgICBwcm90ZWN0ZWQgX2RvY3VtZW50OiBEb2N1bWVudDtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIF9yZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgICAgICByZWFkb25seSBfZWxlbWVudFJlZjogRWxlbWVudFJlZjxIVE1MRWxlbWVudD4sXG4gICAgICAgIHByaXZhdGUgY2Q6IENoYW5nZURldGVjdG9yUmVmLFxuICAgICAgICBwcml2YXRlIF9uZ1pvbmU6IE5nWm9uZSxcbiAgICAgICAgQEluamVjdChET0NVTUVOVCkgX2RvY3VtZW50OiBhbnksXG4gICAgICAgIHZpZXdQb3J0UnVsZXI6IFZpZXdwb3J0UnVsZXJcbiAgICApIHtcbiAgICAgICAgdGhpcy5fZG9jdW1lbnQgPSBfZG9jdW1lbnQ7XG4gICAgICAgIHZpZXdQb3J0UnVsZXIuY2hhbmdlKClcbiAgICAgICAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLl9kZXN0cm95KSlcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT5cbiAgICAgICAgICAgICAgICB0aGlzLl9uZ1pvbmUucnVuKCgpID0+IHRoaXMudXBkYXRlQ3JvcHBlclBvc2l0aW9uKCkpXG4gICAgICAgICAgICApO1xuICAgIH1cblxuICAgIHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fbmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLl9pbWdDb250YWluZXIubmF0aXZlRWxlbWVudDtcbiAgICAgICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNlZG93blwiLCB0aGlzLl9wb2ludGVyRG93biwgYWN0aXZlRXZlbnRPcHRpb25zKTtcbiAgICAgICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNoc3RhcnRcIiwgdGhpcy5fcG9pbnRlckRvd24sIGFjdGl2ZUV2ZW50T3B0aW9ucyk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fZGVzdHJveS5uZXh0KCk7XG4gICAgICAgIHRoaXMuX2Rlc3Ryb3kuY29tcGxldGUoKTtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuX2ltZ0NvbnRhaW5lci5uYXRpdmVFbGVtZW50O1xuICAgICAgICB0aGlzLl9sYXN0UG9pbnRlckV2ZW50ID0gbnVsbDtcbiAgICAgICAgdGhpcy5fcmVtb3ZlR2xvYmFsRXZlbnRzKCk7XG4gICAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1vdXNlZG93blwiLCB0aGlzLl9wb2ludGVyRG93biwgYWN0aXZlRXZlbnRPcHRpb25zKTtcbiAgICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2hzdGFydFwiLCB0aGlzLl9wb2ludGVyRG93biwgYWN0aXZlRXZlbnRPcHRpb25zKTtcbiAgICB9XG5cbiAgICAvKiogTG9hZCBpbWFnZSB3aXRoIGNhbnZhcyAqL1xuICAgIHByaXZhdGUgX2ltZ0xvYWRlZChpbWdFbGVtZW50OiBIVE1MSW1hZ2VFbGVtZW50KTogdm9pZCB7XG4gICAgICAgIGlmIChpbWdFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLl9pbWcgPSBpbWdFbGVtZW50O1xuICAgICAgICAgICAgY29uc3QgY2FudmFzID0gdGhpcy5faW1nQ2FudmFzLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgICAgICBjYW52YXMud2lkdGggPSBpbWdFbGVtZW50LndpZHRoO1xuICAgICAgICAgICAgY2FudmFzLmhlaWdodCA9IGltZ0VsZW1lbnQuaGVpZ2h0O1xuICAgICAgICAgICAgY29uc3QgY3R4ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcbiAgICAgICAgICAgIGN0eC5jbGVhclJlY3QoMCwgMCwgaW1nRWxlbWVudC53aWR0aCwgaW1nRWxlbWVudC5oZWlnaHQpO1xuICAgICAgICAgICAgY3R4LmRyYXdJbWFnZShpbWdFbGVtZW50LCAwLCAwKTtcblxuICAgICAgICAgICAgLyoqIHNldCBtaW4gc2NhbGUgKi9cbiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZU1pblNjYWxlKGNhbnZhcyk7XG4gICAgICAgICAgICB0aGlzLl91cGRhdGVNYXhTY2FsZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfc2V0U3R5bGVzRm9yQ29udEltZyh2YWx1ZXM6IHsgeD86IG51bWJlciwgeT86IG51bWJlciB9KSB7XG4gICAgICAgIGNvbnN0IG5ld1N0eWxlcyA9IHsgfSBhcyBhbnk7XG4gICAgICAgIGlmICh2YWx1ZXMueCAhPSBudWxsICYmIHZhbHVlcy55ICE9IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnN0IHJvb3RSZWN0ID0gdGhpcy5fcm9vdFJlY3QoKTtcbiAgICAgICAgICAgIGNvbnN0IHggPSByb290UmVjdC53aWR0aCAvIDIgLSAodmFsdWVzLngpO1xuICAgICAgICAgICAgY29uc3QgeSA9IHJvb3RSZWN0LmhlaWdodCAvIDIgLSAodmFsdWVzLnkpO1xuXG4gICAgICAgICAgICB0aGlzLl9pbWdSZWN0LnggPSAodmFsdWVzLngpO1xuICAgICAgICAgICAgdGhpcy5faW1nUmVjdC55ID0gKHZhbHVlcy55KTtcbiAgICAgICAgICAgIHRoaXMuX2ltZ1JlY3QueGMgPSAoeCk7XG4gICAgICAgICAgICB0aGlzLl9pbWdSZWN0LnljID0gKHkpO1xuXG4gICAgICAgIH1cbiAgICAgICAgbmV3U3R5bGVzLnRyYW5zZm9ybSA9IGB0cmFuc2xhdGUzZCgkeyh0aGlzLl9pbWdSZWN0LngpfXB4LCR7KHRoaXMuX2ltZ1JlY3QueSl9cHgsIDApYDtcbiAgICAgICAgbmV3U3R5bGVzLnRyYW5zZm9ybSArPSBgc2NhbGUoJHt0aGlzLl9zY2FsM0ZpeH0pYDtcbiAgICAgICAgbmV3U3R5bGVzLnRyYW5zZm9ybU9yaWdpbiA9IGAke3RoaXMuX2ltZ1JlY3QueGN9cHggJHt0aGlzLl9pbWdSZWN0LnljfXB4IDBgO1xuICAgICAgICBuZXdTdHlsZXNbXCItd2Via2l0LXRyYW5zZm9ybVwiXSA9IG5ld1N0eWxlcy50cmFuc2Zvcm07XG4gICAgICAgIG5ld1N0eWxlc1tcIi13ZWJraXQtdHJhbnNmb3JtLW9yaWdpblwiXSA9IG5ld1N0eWxlcy50cmFuc2Zvcm1PcmlnaW47XG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIG5ld1N0eWxlcykge1xuICAgICAgICAgICAgaWYgKG5ld1N0eWxlcy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcmVuZGVyZXIuc2V0U3R5bGUodGhpcy5faW1nQ29udGFpbmVyLm5hdGl2ZUVsZW1lbnQsIGtleSwgbmV3U3R5bGVzW2tleV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVwZGF0ZSBhcmVhIGFuZCBpbWFnZSBwb3NpdGlvbiBvbmx5IGlmIG5lZWRlZCxcbiAgICAgKiB0aGlzIGlzIHVzZWQgd2hlbiB3aW5kb3cgcmVzaXplXG4gICAgICovXG4gICAgcHVibGljIHVwZGF0ZUNyb3BwZXJQb3NpdGlvbigpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuaXNMb2FkZWQpIHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlUG9zaXRpb24oKTtcbiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUFyZWFJZk5lZWRlZCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIExvYWQgSW1hZ2UgZnJvbSBpbnB1dCBldmVudCAqL1xuICAgIHB1YmxpYyBzZWxlY3RJbnB1dEV2ZW50KGltZzogRXZlbnQpIHtcbiAgICAgICAgdGhpcy5fY3VycmVudElucHV0RWxlbWVudCA9IGltZy50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICAgICAgY29uc3QgX2ltZyA9IGltZy50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudDtcbiAgICAgICAgaWYgKF9pbWcuZmlsZXMgJiYgX2ltZy5maWxlcy5sZW5ndGggIT09IDEpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBmaWxlU2l6ZSA9IF9pbWcuZmlsZXNbMF0uc2l6ZTtcbiAgICAgICAgY29uc3QgZmlsZU5hbWUgPSBfaW1nLnZhbHVlLnJlcGxhY2UoLy4qKFxcL3xcXFxcKS8sIFwiXCIpO1xuXG4gICAgICAgIGlmICh0aGlzLm1heEZpbGVTaXplICYmIGZpbGVTaXplID4gdGhpcy5tYXhGaWxlU2l6ZSkge1xuICAgICAgICAgICAgY29uc3QgY3JvcEV2ZW50OiBJbWdDcm9wcGVyRXJyb3JFdmVudCA9IHtcbiAgICAgICAgICAgICAgICBuYW1lOiBmaWxlTmFtZSxcbiAgICAgICAgICAgICAgICB0eXBlOiBfaW1nLmZpbGVzWzBdLnR5cGUsXG4gICAgICAgICAgICAgICAgc2l6ZTogZmlsZVNpemUsXG4gICAgICAgICAgICAgICAgZXJyb3I6IEltZ0Nyb3BwZXJFcnJvci5TaXplXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdGhpcy5jbGVhbigpO1xuICAgICAgICAgICAgdGhpcy5lcnJvci5lbWl0KGNyb3BFdmVudCBhcyBJbWdDcm9wcGVyRXJyb3JFdmVudCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBuZXcgT2JzZXJ2YWJsZTxQcm9ncmVzc0V2ZW50PihvYnNlcnZlciA9PiB7XG5cbiAgICAgICAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG5cbiAgICAgICAgICAgIHJlYWRlci5vbmVycm9yID0gZXJyID0+IG9ic2VydmVyLmVycm9yKGVycik7XG4gICAgICAgICAgICByZWFkZXIub25hYm9ydCA9IGVyciA9PiBvYnNlcnZlci5lcnJvcihlcnIpO1xuICAgICAgICAgICAgcmVhZGVyLm9ubG9hZCA9IChldikgPT4gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dChldik7XG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICByZWFkZXIucmVhZEFzRGF0YVVSTChfaW1nLmZpbGVzWzBdKTtcbiAgICAgICAgfSlcbiAgICAgICAgICAgIC5waXBlKHRha2UoMSksIHRha2VVbnRpbCh0aGlzLl9kZXN0cm95KSlcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoXG4gICAgICAgICAgICAgICAgKGxvYWRFdmVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvcmlnaW5hbERhdGFVUkwgPSAobG9hZEV2ZW50LnRhcmdldCBhcyBGaWxlUmVhZGVyKS5yZXN1bHQgYXMgc3RyaW5nO1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9hZEltYWdlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IGZpbGVOYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZTogX2ltZy5maWxlc1swXS5zaXplLCAvLyBzaXplIGluIGJ5dGVzXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiB0aGlzLmNvbmZpZy50eXBlIHx8IF9pbWcuZmlsZXNbMF0udHlwZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsRGF0YVVSTFxuICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNkLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjcm9wRXZlbnQ6IEltZ0Nyb3BwZXJFcnJvckV2ZW50ID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogZmlsZU5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBzaXplOiBmaWxlU2l6ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yOiBJbWdDcm9wcGVyRXJyb3IuT3RoZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1zZzogXCJUaGUgRmlsZSBjb3VsZCBub3QgYmUgbG9hZGVkLlwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogX2ltZy5maWxlc1swXS50eXBlXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2xlYW4oKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lcnJvci5lbWl0KGNyb3BFdmVudCBhcyBJbWdDcm9wcGVyRXJyb3JFdmVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcblxuICAgIH1cblxuICAgIC8qKiBTZXQgdGhlIHNpemUgb2YgdGhlIGltYWdlLCB0aGUgdmFsdWVzIGNhbiBiZSAwIGJldHdlZW4gMSwgd2hlcmUgMSBpcyB0aGUgb3JpZ2luYWwgc2l6ZSAqL1xuICAgIHB1YmxpYyBzZXRTY2FsZShzaXplPzogbnVtYmVyLCBub0F1dG9Dcm9wPzogYm9vbGVhbikge1xuICAgICAgICAvLyBmaXggbWluIHNjYWxlXG4gICAgICAgIGNvbnN0IG5ld1NpemUgPSBzaXplID49IHRoaXMubWluU2NhbGUgJiYgc2l6ZSA8PSAxID8gc2l6ZSA6IHRoaXMubWluU2NhbGU7XG5cbiAgICAgICAgLy8gY2hlY2tcbiAgICAgICAgY29uc3QgY2hhbmdlZCA9IHNpemUgIT0gbnVsbCAmJiBzaXplICE9PSB0aGlzLnNjYWxlICYmIG5ld1NpemUgIT09IHRoaXMuc2NhbGU7XG4gICAgICAgIHRoaXMuX3NjYWxlID0gc2l6ZTtcbiAgICAgICAgaWYgKCFjaGFuZ2VkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc2NhbDNGaXggPSBuZXdTaXplO1xuICAgICAgICB0aGlzLl91cGRhdGVBYnNvbHV0ZVNjYWxlKCk7XG4gICAgICAgIGlmICh0aGlzLmlzTG9hZGVkKSB7XG4gICAgICAgICAgICBpZiAoY2hhbmdlZCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9yaWdpblBvc2l0aW9uID0gey4uLnRoaXMuX2ltZ1JlY3R9O1xuICAgICAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0ge1xuICAgICAgICAgICAgICAgICAgICB4OiBvcmlnaW5Qb3NpdGlvbi54LFxuICAgICAgICAgICAgICAgICAgICB5OiBvcmlnaW5Qb3NpdGlvbi55LFxuICAgICAgICAgICAgICAgICAgICBsZWZ0OiBvcmlnaW5Qb3NpdGlvbi54YyxcbiAgICAgICAgICAgICAgICAgICAgdG9wOiBvcmlnaW5Qb3NpdGlvbi55Y1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5fc2V0U3R5bGVzRm9yQ29udEltZyh7fSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2ltdWxhdGVQb2ludGVyTW92ZSgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5taW5TY2FsZSkge1xuICAgICAgICAgICAgdGhpcy5fc2V0U3R5bGVzRm9yQ29udEltZyh7XG4gICAgICAgICAgICAgICAgLi4udGhpcy5fZ2V0Q2VudGVyUG9pbnRzKClcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zY2FsZUNoYW5nZS5lbWl0KHNpemUpO1xuICAgICAgICBpZiAoIW5vQXV0b0Nyb3ApIHtcbiAgICAgICAgICAgIHRoaXMuX2Nyb3BJZkF1dG9Dcm9wKCk7XG4gICAgICAgIH1cblxuICAgIH1cblxuICAgIHByaXZhdGUgX2dldENlbnRlclBvaW50cygpIHtcbiAgICAgICAgY29uc3Qgcm9vdCA9IHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgY29uc3QgaW1nID0gdGhpcy5faW1nQ2FudmFzLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgIGNvbnN0IHggPSAocm9vdC5vZmZzZXRXaWR0aCAtIChpbWcud2lkdGgpKSAvIDI7XG4gICAgICAgIGNvbnN0IHkgPSAocm9vdC5vZmZzZXRIZWlnaHQgLSAoaW1nLmhlaWdodCkpIC8gMjtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHgsXG4gICAgICAgICAgICB5XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRml0IHRvIHNjcmVlblxuICAgICAqL1xuICAgIHB1YmxpYyBmaXRUb1NjcmVlbigpIHtcbiAgICAgICAgY29uc3QgY29udGFpbmVyID0gdGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50IGFzIEhUTUxFbGVtZW50O1xuICAgICAgICBjb25zdCBtaW4gPSB7XG4gICAgICAgICAgICB3aWR0aDogY29udGFpbmVyLm9mZnNldFdpZHRoLFxuICAgICAgICAgICAgaGVpZ2h0OiBjb250YWluZXIub2Zmc2V0SGVpZ2h0XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHsgd2lkdGgsIGhlaWdodCB9ID0gdGhpcy5faW1nO1xuICAgICAgICBjb25zdCBtaW5TY2FsZSA9IHtcbiAgICAgICAgICAgIHdpZHRoOiBtaW4ud2lkdGggLyB3aWR0aCxcbiAgICAgICAgICAgIGhlaWdodDogbWluLmhlaWdodCAvIGhlaWdodFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCByZXN1bHQgPSBNYXRoLm1heChtaW5TY2FsZS53aWR0aCwgbWluU2NhbGUuaGVpZ2h0KTtcbiAgICAgICAgdGhpcy5zZXRTY2FsZShyZXN1bHQpO1xuICAgIH1cblxuICAgIHB1YmxpYyBmaXQoKSB7XG4gICAgICAgIHRoaXMuc2V0U2NhbGUodGhpcy5taW5TY2FsZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcG9pbnRlckRvd24gPSAoZXZlbnQ6IFRvdWNoRXZlbnQgfCBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICAgIC8vIERvbid0IGRvIGFueXRoaW5nIGlmIHRoZVxuICAgICAgICAvLyB1c2VyIGlzIHVzaW5nIGFueXRoaW5nIG90aGVyIHRoYW4gdGhlIG1haW4gbW91c2UgYnV0dG9uLlxuICAgICAgICBpZiAodGhpcy5faXNTbGlkaW5nIHx8ICghaXNUb3VjaEV2ZW50KGV2ZW50KSAmJiBldmVudC5idXR0b24gIT09IDApKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX2lzU2xpZGluZyA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLm9mZnNldCA9IHtcbiAgICAgICAgICAgICAgICB4OiB0aGlzLl9pbWdSZWN0LngsXG4gICAgICAgICAgICAgICAgeTogdGhpcy5faW1nUmVjdC55LFxuICAgICAgICAgICAgICAgIGxlZnQ6IHRoaXMuX2ltZ1JlY3QueGMsXG4gICAgICAgICAgICAgICAgdG9wOiB0aGlzLl9pbWdSZWN0LnljXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdGhpcy5fbGFzdFBvaW50ZXJFdmVudCA9IGV2ZW50O1xuICAgICAgICAgICAgdGhpcy5fc3RhcnRQb2ludGVyRXZlbnQgPSBnZXRHZXN0dXJlUG9pbnRGcm9tRXZlbnQoZXZlbnQpO1xuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIHRoaXMuX2JpbmRHbG9iYWxFdmVudHMoZXZlbnQpO1xuICAgICAgICB9KTtcblxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNpbXVsYXRlIHBvaW50ZXJNb3ZlIHdpdGggY2xpZW50WCA9IDAgYW5kIGNsaWVudFkgPSAwLFxuICAgICAqIHRoaXMgaXMgdXNlZCBieSBgc2V0U2NhbGVgIGFuZCBgcm90YXRlYFxuICAgICAqL1xuICAgIHByaXZhdGUgX3NpbXVsYXRlUG9pbnRlck1vdmUoKSB7XG4gICAgICAgIHRoaXMuX2lzU2xpZGluZyA9IHRydWU7XG4gICAgICAgIHRoaXMuX3N0YXJ0UG9pbnRlckV2ZW50ID0ge1xuICAgICAgICAgICAgeDogMCxcbiAgICAgICAgICAgIHk6IDBcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5fcG9pbnRlck1vdmUoe1xuICAgICAgICAgICAgY2xpZW50WDogMCxcbiAgICAgICAgICAgIGNsaWVudFk6IDAsXG4gICAgICAgICAgICB0eXBlOiBcIm5cIixcbiAgICAgICAgICAgIHByZXZlbnREZWZhdWx0OiAoKSA9PiB7fVxuICAgICAgICB9IGFzIE1vdXNlRXZlbnQpO1xuICAgICAgICB0aGlzLl9pc1NsaWRpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fc3RhcnRQb2ludGVyRXZlbnQgPSBudWxsO1xuICAgIH1cblxuICAgIHB1YmxpYyBfbWFya0ZvckNoZWNrKCkge1xuICAgICAgICB0aGlzLmNkLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGxlZCB3aGVuIHRoZSB1c2VyIGhhcyBtb3ZlZCB0aGVpciBwb2ludGVyIGFmdGVyXG4gICAgICogc3RhcnRpbmcgdG8gZHJhZy5cbiAgICAgKi9cbiAgICBwcml2YXRlIF9wb2ludGVyTW92ZSA9IChldmVudDogVG91Y2hFdmVudCB8IE1vdXNlRXZlbnQpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuX2lzU2xpZGluZykge1xuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIHRoaXMuX2xhc3RQb2ludGVyRXZlbnQgPSBldmVudDtcbiAgICAgICAgICAgIGxldCB4OiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gICAgICAgICAgICBsZXQgeTogbnVtYmVyIHwgdW5kZWZpbmVkO1xuICAgICAgICAgICAgY29uc3QgY2FudmFzID0gdGhpcy5faW1nQ2FudmFzLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgICAgICBjb25zdCBzY2FsZUZpeCA9IHRoaXMuX3NjYWwzRml4O1xuICAgICAgICAgICAgY29uc3QgY29uZmlnID0gdGhpcy5jb25maWc7XG4gICAgICAgICAgICBjb25zdCBzdGFydFAgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgICAgIGNvbnN0IHBvaW50ID0gZ2V0R2VzdHVyZVBvaW50RnJvbUV2ZW50KGV2ZW50KTtcbiAgICAgICAgICAgIGNvbnN0IGRlbHRhWCA9IHBvaW50LnggLSB0aGlzLl9zdGFydFBvaW50ZXJFdmVudC54O1xuICAgICAgICAgICAgY29uc3QgZGVsdGFZID0gcG9pbnQueSAtIHRoaXMuX3N0YXJ0UG9pbnRlckV2ZW50Lnk7XG4gICAgICAgICAgICBpZiAoIXNjYWxlRml4IHx8ICFzdGFydFApIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGlzTWluU2NhbGVZID0gY2FudmFzLmhlaWdodCAqIHNjYWxlRml4IDwgY29uZmlnLmhlaWdodCAmJiBjb25maWcuZXh0cmFab29tT3V0O1xuICAgICAgICAgICAgY29uc3QgaXNNaW5TY2FsZVggPSBjYW52YXMud2lkdGggKiBzY2FsZUZpeCA8IGNvbmZpZy53aWR0aCAmJiBjb25maWcuZXh0cmFab29tT3V0O1xuXG4gICAgICAgICAgICBjb25zdCBsaW1pdExlZnQgPSAoY29uZmlnLndpZHRoIC8gMiAvIHNjYWxlRml4KSA+PSBzdGFydFAubGVmdCAtIChkZWx0YVggLyBzY2FsZUZpeCk7XG4gICAgICAgICAgICBjb25zdCBsaW1pdFJpZ2h0ID0gKGNvbmZpZy53aWR0aCAvIDIgLyBzY2FsZUZpeCkgK1xuICAgICAgICAgICAgICAgIChjYW52YXMud2lkdGgpIC0gKHN0YXJ0UC5sZWZ0IC0gKGRlbHRhWCAvIHNjYWxlRml4KSkgPD0gY29uZmlnLndpZHRoIC8gc2NhbGVGaXg7XG4gICAgICAgICAgICBjb25zdCBsaW1pdFRvcCA9ICgoY29uZmlnLmhlaWdodCAvIDIgLyBzY2FsZUZpeCkgPj0gKHN0YXJ0UC50b3AgLSAoZGVsdGFZIC8gc2NhbGVGaXgpKSk7XG4gICAgICAgICAgICBjb25zdCBsaW1pdEJvdHRvbSA9IChcbiAgICAgICAgICAgICAgICAoKGNvbmZpZy5oZWlnaHQgLyAyIC8gc2NhbGVGaXgpICsgKGNhbnZhcy5oZWlnaHQpIC0gKHN0YXJ0UC50b3AgLSAoZGVsdGFZIC8gc2NhbGVGaXgpKSkgPD0gKGNvbmZpZy5oZWlnaHQgLyBzY2FsZUZpeClcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIC8vIExpbWl0IGZvciBsZWZ0XG4gICAgICAgICAgICBpZiAoKGxpbWl0TGVmdCAmJiAhaXNNaW5TY2FsZVgpIHx8ICghbGltaXRMZWZ0ICYmIGlzTWluU2NhbGVYKSkge1xuICAgICAgICAgICAgICAgIHggPSBzdGFydFAueCArIChzdGFydFAubGVmdCkgLSAoY29uZmlnLndpZHRoIC8gMiAvIHNjYWxlRml4KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gTGltaXQgZm9yIHJpZ2h0XG4gICAgICAgICAgICBpZiAoKGxpbWl0UmlnaHQgJiYgIWlzTWluU2NhbGVYKSB8fCAoIWxpbWl0UmlnaHQgJiYgaXNNaW5TY2FsZVgpKSB7XG4gICAgICAgICAgICAgICAgeCA9IHN0YXJ0UC54ICsgKHN0YXJ0UC5sZWZ0KSArIChjb25maWcud2lkdGggLyAyIC8gc2NhbGVGaXgpIC0gY2FudmFzLndpZHRoO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBMaW1pdCBmb3IgdG9wXG4gICAgICAgICAgICBpZiAoKGxpbWl0VG9wICYmICFpc01pblNjYWxlWSkgfHwgKCFsaW1pdFRvcCAmJiBpc01pblNjYWxlWSkpIHtcbiAgICAgICAgICAgICAgICB5ID0gc3RhcnRQLnkgKyAoc3RhcnRQLnRvcCkgLSAoY29uZmlnLmhlaWdodCAvIDIgLyBzY2FsZUZpeCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIExpbWl0IGZvciBib3R0b21cbiAgICAgICAgICAgIGlmICgobGltaXRCb3R0b20gJiYgIWlzTWluU2NhbGVZKSB8fCAoIWxpbWl0Qm90dG9tICYmIGlzTWluU2NhbGVZKSkge1xuICAgICAgICAgICAgICAgIHkgPSBzdGFydFAueSArIChzdGFydFAudG9wKSArIChjb25maWcuaGVpZ2h0IC8gMiAvIHNjYWxlRml4KSAtIGNhbnZhcy5oZWlnaHQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFdoZW4gcHJlc3Mgc2hpZnRLZXksIGRlcHJlY2F0ZWRcbiAgICAgICAgICAgIC8vIGlmIChldmVudC5zcmNFdmVudCAmJiBldmVudC5zcmNFdmVudC5zaGlmdEtleSkge1xuICAgICAgICAgICAgLy8gICBpZiAoTWF0aC5hYnMoZXZlbnQuZGVsdGFYKSA9PT0gTWF0aC5tYXgoTWF0aC5hYnMoZXZlbnQuZGVsdGFYKSwgTWF0aC5hYnMoZXZlbnQuZGVsdGFZKSkpIHtcbiAgICAgICAgICAgIC8vICAgICB5ID0gdGhpcy5vZmZzZXQudG9wO1xuICAgICAgICAgICAgLy8gICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gICAgIHggPSB0aGlzLm9mZnNldC5sZWZ0O1xuICAgICAgICAgICAgLy8gICB9XG4gICAgICAgICAgICAvLyB9XG5cbiAgICAgICAgICAgIGlmICh4ID09PSB2b2lkIDApIHsgeCA9IChkZWx0YVggLyBzY2FsZUZpeCkgKyAoc3RhcnRQLngpOyB9XG4gICAgICAgICAgICBpZiAoeSA9PT0gdm9pZCAwKSB7IHkgPSAoZGVsdGFZIC8gc2NhbGVGaXgpICsgKHN0YXJ0UC55KTsgfVxuICAgICAgICAgICAgdGhpcy5fc2V0U3R5bGVzRm9yQ29udEltZyh7XG4gICAgICAgICAgICAgICAgeCwgeVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgdXBkYXRlUG9zaXRpb24oKTogdm9pZDtcbiAgICBwdWJsaWMgdXBkYXRlUG9zaXRpb24oeE9yaWdpbjogbnVtYmVyLCB5T3JpZ2luOiBudW1iZXIpOiB2b2lkO1xuICAgIHB1YmxpYyB1cGRhdGVQb3NpdGlvbih4T3JpZ2luPzogbnVtYmVyLCB5T3JpZ2luPzogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGhvc3RSZWN0ID0gdGhpcy5fcm9vdFJlY3QoKTtcbiAgICAgICAgY29uc3QgYXJlYVJlY3QgPSB0aGlzLl9hcmVhQ3JvcHBlclJlY3QoKTtcbiAgICAgICAgY29uc3QgYXJlYVdpZHRoID0gYXJlYVJlY3Qud2lkdGggPiBob3N0UmVjdC53aWR0aFxuICAgICAgICAgICAgPyBob3N0UmVjdC53aWR0aFxuICAgICAgICAgICAgOiBhcmVhUmVjdC53aWR0aDtcbiAgICAgICAgY29uc3QgYXJlYUhlaWdodCA9IGFyZWFSZWN0LmhlaWdodCA+IGhvc3RSZWN0LmhlaWdodFxuICAgICAgICAgICAgPyBob3N0UmVjdC5oZWlnaHRcbiAgICAgICAgICAgIDogYXJlYVJlY3QuaGVpZ2h0O1xuICAgICAgICBsZXQgeDogbnVtYmVyO1xuICAgICAgICBsZXQgeTogbnVtYmVyO1xuICAgICAgICBpZiAoeE9yaWdpbiA9PSBudWxsICYmIHlPcmlnaW4gPT0gbnVsbCkge1xuICAgICAgICAgICAgeE9yaWdpbiA9IHRoaXMuX2ltZ1JlY3QueGM7XG4gICAgICAgICAgICB5T3JpZ2luID0gdGhpcy5faW1nUmVjdC55YztcbiAgICAgICAgfVxuICAgICAgICB4ID0gKGFyZWFSZWN0LmxlZnQgLSBob3N0UmVjdC5sZWZ0KTtcbiAgICAgICAgeSA9IChhcmVhUmVjdC50b3AgLSBob3N0UmVjdC50b3ApO1xuICAgICAgICB4IC09ICh4T3JpZ2luIC0gKGFyZWFXaWR0aCAvIDIpKTtcbiAgICAgICAgeSAtPSAoeU9yaWdpbiAtIChhcmVhSGVpZ2h0IC8gMikpO1xuXG4gICAgICAgIHRoaXMuX3NldFN0eWxlc0ZvckNvbnRJbWcoe1xuICAgICAgICAgICAgeCwgeVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgX3NsaWRlRW5kKCkge1xuICAgICAgICB0aGlzLl9jcm9wSWZBdXRvQ3JvcCgpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX2Nyb3BJZkF1dG9Dcm9wKCkge1xuICAgICAgICBpZiAodGhpcy5jb25maWcuYXV0b0Nyb3ApIHtcbiAgICAgICAgICAgIHRoaXMuY3JvcCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqICsgKi9cbiAgICBwdWJsaWMgem9vbUluKCkge1xuICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuX3NjYWwzRml4ICsgLjA1O1xuICAgICAgICBpZiAoc2NhbGUgPiB0aGlzLm1pblNjYWxlICYmIHNjYWxlIDw9IHRoaXMuX21heFNjYWxlKSB7XG4gICAgICAgICAgICB0aGlzLnNldFNjYWxlKHNjYWxlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U2NhbGUodGhpcy5fbWF4U2NhbGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIENsZWFuIHRoZSBpbWcgY3JvcHBlciAqL1xuICAgIHB1YmxpYyBjbGVhbigpIHtcbiAgICAgICAgLy8gZml4IGNob29zaW5nIHRoZSBzYW1lIGltYWdlIGRvZXMgbm90IGxvYWRcbiAgICAgICAgaWYgKHRoaXMuX2N1cnJlbnRJbnB1dEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX2N1cnJlbnRJbnB1dEVsZW1lbnQudmFsdWUgPSBcIlwiO1xuICAgICAgICAgICAgdGhpcy5fY3VycmVudElucHV0RWxlbWVudCA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuaXNMb2FkZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX2ltZ1JlY3QgPSB7IH0gYXMgYW55O1xuICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0aGlzLnNjYWxlID0gdW5kZWZpbmVkIGFzIGFueTtcbiAgICAgICAgICAgIHRoaXMuX3NjYWwzRml4ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgdGhpcy5fcm90YXRpb24gPSAwO1xuICAgICAgICAgICAgdGhpcy5fbWluU2NhbGUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0aGlzLl9pc0xvYWRlZEltZyA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5pc0xvYWRlZCA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5pc0Nyb3BwZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuX2N1cnJlbnRMb2FkQ29uZmlnID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgdGhpcy5jb25maWcgPSB0aGlzLl9jb25maWdQcmltYXJ5O1xuICAgICAgICAgICAgY29uc3QgY2FudmFzID0gdGhpcy5faW1nQ2FudmFzLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgICAgICBjYW52YXMud2lkdGggPSAwO1xuICAgICAgICAgICAgY2FudmFzLmhlaWdodCA9IDA7XG4gICAgICAgICAgICB0aGlzLmNsZWFuZWQuZW1pdChudWxsKTtcbiAgICAgICAgICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogLSAqL1xuICAgIHB1YmxpYyB6b29tT3V0KCkge1xuICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuX3NjYWwzRml4IC0gLjA1O1xuICAgICAgICBpZiAoc2NhbGUgPiB0aGlzLm1pblNjYWxlICYmIHNjYWxlIDw9IHRoaXMuX21heFNjYWxlKSB7XG4gICAgICAgICAgICB0aGlzLnNldFNjYWxlKHNjYWxlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZml0KCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcHVibGljIGNlbnRlcigpIHtcbiAgICAgICAgY29uc3QgbmV3U3R5bGVzID0ge1xuICAgICAgICAgICAgLi4udGhpcy5fZ2V0Q2VudGVyUG9pbnRzKClcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5fc2V0U3R5bGVzRm9yQ29udEltZyhuZXdTdHlsZXMpO1xuICAgICAgICB0aGlzLl9jcm9wSWZBdXRvQ3JvcCgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBsb2FkIGFuIGltYWdlIGZyb20gYSBnaXZlbiBjb25maWd1cmF0aW9uLFxuICAgICAqIG9yIGZyb20gdGhlIHJlc3VsdCBvZiBhIGNyb3BwZWQgaW1hZ2VcbiAgICAgKi9cbiAgICBwdWJsaWMgbG9hZEltYWdlKGNvbmZpZzogSW1nQ3JvcHBlckxvYWRlckNvbmZpZyB8IHN0cmluZywgZm4/OiAoKSA9PiB2b2lkKSB7XG4gICAgICAgIHRoaXMuY2xlYW4oKTtcbiAgICAgICAgY29uc3QgX2NvbmZpZyA9IHRoaXMuX2N1cnJlbnRMb2FkQ29uZmlnID0gdHlwZW9mIGNvbmZpZyA9PT0gXCJzdHJpbmdcIlxuICAgICAgICAgICAgPyB7IG9yaWdpbmFsRGF0YVVSTDogY29uZmlnIH1cbiAgICAgICAgICAgIDogeyAuLi5jb25maWcgfTtcbiAgICAgICAgbGV0IHNyYyA9IF9jb25maWcub3JpZ2luYWxEYXRhVVJMO1xuICAgICAgICB0aGlzLl9wcmltYXJ5QXJlYVdpZHRoID0gdGhpcy5fY29uZmlnUHJpbWFyeS53aWR0aDtcbiAgICAgICAgdGhpcy5fcHJpbWFyeUFyZWFIZWlnaHQgPSB0aGlzLl9jb25maWdQcmltYXJ5LmhlaWdodDtcbiAgICAgICAgaWYgKF9jb25maWcuYXJlYVdpZHRoICYmIF9jb25maWcuYXJlYUhlaWdodCkge1xuICAgICAgICAgICAgdGhpcy5jb25maWcud2lkdGggPSBfY29uZmlnLmFyZWFXaWR0aDtcbiAgICAgICAgICAgIHRoaXMuY29uZmlnLmhlaWdodCA9IF9jb25maWcuYXJlYUhlaWdodDtcbiAgICAgICAgfVxuICAgICAgICBzcmMgPSBub3JtYWxpemVTVkcoc3JjKTtcblxuICAgICAgICBjb25zdCBpbWcgPSBjcmVhdGVIdG1sSW1nKHNyYyk7XG5cbiAgICAgICAgY29uc3QgY3JvcEV2ZW50ID0geyAuLi5fY29uZmlnIH0gYXMgSW1nQ3JvcHBlckV2ZW50O1xuXG4gICAgICAgIG5ldyBPYnNlcnZhYmxlPHZvaWQ+KG9ic2VydmVyID0+IHtcblxuICAgICAgICAgICAgaW1nLm9uZXJyb3IgPSBlcnIgPT4gb2JzZXJ2ZXIuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgIGltZy5vbmFib3J0ID0gZXJyID0+IG9ic2VydmVyLmVycm9yKGVycik7XG4gICAgICAgICAgICBpbWcub25sb2FkID0gKCkgPT4gb2JzZXJ2ZXIubmV4dChudWxsKTtcbiAgICAgICAgfSlcbiAgICAgICAgICAgIC5waXBlKHRha2UoMSksIHRha2VVbnRpbCh0aGlzLl9kZXN0cm95KSlcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoXG4gICAgICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9pbWdMb2FkZWQoaW1nKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5faXNMb2FkZWRJbWcgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmltYWdlTG9hZGVkLmVtaXQoY3JvcEV2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jZC5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX25nWm9uZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5vblN0YWJsZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hc09ic2VydmFibGUoKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5waXBlKHRha2UoMSksIHRha2VVbnRpbCh0aGlzLl9kZXN0cm95KSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKSA9PiBzZXRUaW1lb3V0KCgpID0+IHRoaXMuX25nWm9uZS5ydW4oKCkgPT4gdGhpcy5fcG9zaXRpb25JbWcoY3JvcEV2ZW50LCBmbikpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvcjogSW1nQ3JvcHBlckVycm9yRXZlbnQgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBfY29uZmlnLm5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvcjogSW1nQ3JvcHBlckVycm9yLlR5cGUsXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBfY29uZmlnLnR5cGUsXG4gICAgICAgICAgICAgICAgICAgICAgICBzaXplOiBfY29uZmlnLnNpemVcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lcnJvci5lbWl0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3VwZGF0ZUFyZWFJZk5lZWRlZCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9jb25maWcucmVzcG9uc2l2ZUFyZWEpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJvb3RSZWN0ID0gdGhpcy5fcm9vdFJlY3QoKTtcbiAgICAgICAgY29uc3QgYXJlYVJlY3QgPSB0aGlzLl9hcmVhQ3JvcHBlclJlY3QoKTtcbiAgICAgICAgY29uc3QgbWluV2lkdGggPSB0aGlzLmNvbmZpZy5taW5XaWR0aCB8fCAxO1xuICAgICAgICBjb25zdCBtaW5IZWlnaHQgPSB0aGlzLmNvbmZpZy5taW5IZWlnaHQgfHwgMTtcbiAgICAgICAgaWYgKCEoXG4gICAgICAgICAgICBhcmVhUmVjdC53aWR0aCA+IHJvb3RSZWN0LndpZHRoXG4gICAgICAgICAgICB8fCBhcmVhUmVjdC5oZWlnaHQgPiByb290UmVjdC5oZWlnaHRcbiAgICAgICAgICAgIHx8IGFyZWFSZWN0LndpZHRoIDwgdGhpcy5fcHJpbWFyeUFyZWFXaWR0aFxuICAgICAgICAgICAgfHwgYXJlYVJlY3QuaGVpZ2h0IDwgdGhpcy5fcHJpbWFyeUFyZWFIZWlnaHRcbiAgICAgICAgKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFyZWFXaWR0aENvbmYgPSBNYXRoLm1heCh0aGlzLmNvbmZpZy53aWR0aCwgbWluV2lkdGgpO1xuICAgICAgICBjb25zdCBhcmVhV2lkdGhNYXggPSBNYXRoLm1heChyb290UmVjdC53aWR0aCwgbWluV2lkdGgpO1xuICAgICAgICBjb25zdCBtaW5Ib3N0ID0gTWF0aC5taW4oXG4gICAgICAgICAgICBNYXRoLm1heChyb290UmVjdC53aWR0aCwgbWluV2lkdGgpLCBNYXRoLm1heChyb290UmVjdC5oZWlnaHQsIG1pbkhlaWdodClcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgY3VycmVudFNjYWxlID0gdGhpcy5fc2NhbDNGaXg7XG4gICAgICAgIGxldCBuZXdTY2FsZSA9IDA7XG4gICAgICAgIGNvbnN0IHJvdW5kQ29uZiA9IHRoaXMuY29uZmlnLnJvdW5kO1xuXG4gICAgICAgIGlmIChyb3VuZENvbmYpIHtcbiAgICAgICAgICAgIHRoaXMuY29uZmlnLndpZHRoID0gdGhpcy5jb25maWcuaGVpZ2h0ID0gbWluSG9zdDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChhcmVhV2lkdGhDb25mID09PSBhcmVhUmVjdC53aWR0aCkge1xuICAgICAgICAgICAgICAgIGlmIChhcmVhV2lkdGhNYXggPiB0aGlzLl9wcmltYXJ5QXJlYVdpZHRoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnLndpZHRoID0gdGhpcy5fcHJpbWFyeUFyZWFXaWR0aDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWcuaGVpZ2h0ID0gKHRoaXMuX3ByaW1hcnlBcmVhV2lkdGggKiBhcmVhUmVjdC5oZWlnaHQpIC8gYXJlYVJlY3Qud2lkdGg7XG4gICAgICAgICAgICAgICAgICAgIG5ld1NjYWxlID0gKGN1cnJlbnRTY2FsZSAqIHRoaXMuX3ByaW1hcnlBcmVhV2lkdGgpIC8gYXJlYVJlY3Qud2lkdGg7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWcud2lkdGggPSBhcmVhV2lkdGhNYXg7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnLmhlaWdodCA9IChhcmVhV2lkdGhNYXggKiBhcmVhUmVjdC5oZWlnaHQpIC8gYXJlYVJlY3Qud2lkdGg7XG4gICAgICAgICAgICAgICAgICAgIG5ld1NjYWxlID0gKGN1cnJlbnRTY2FsZSAqIGFyZWFXaWR0aE1heCkgLyBhcmVhUmVjdC53aWR0aDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5fdXBkYXRlTWluU2NhbGUoKTtcbiAgICAgICAgICAgICAgICB0aGlzLl91cGRhdGVNYXhTY2FsZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0U2NhbGUobmV3U2NhbGUsIHRydWUpO1xuICAgICAgICAgICAgICAgIHRoaXMuX21hcmtGb3JDaGVjaygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfdXBkYXRlQWJzb2x1dGVTY2FsZSgpIHtcbiAgICAgICAgY29uc3Qgc2NhbGUgPSB0aGlzLl9zY2FsM0ZpeCAvICh0aGlzLmNvbmZpZy53aWR0aCAvIHRoaXMuX3ByaW1hcnlBcmVhV2lkdGgpO1xuICAgICAgICB0aGlzLl9hYnNvbHV0ZVNjYWxlID0gc2NhbGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTG9hZCBJbWFnZSBmcm9tIFVSTFxuICAgICAqIEBkZXByZWNhdGVkIFVzZSBgbG9hZEltYWdlYCBpbnN0ZWFkIG9mIGBzZXRJbWFnZVVybGBcbiAgICAgKiBAcGFyYW0gc3JjIFVSTFxuICAgICAqIEBwYXJhbSBmbiBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgY2FsbGVkIGJlZm9yZSBlbWl0IHRoZSBldmVudCBsb2FkZWRcbiAgICAgKi9cbiAgICBwdWJsaWMgc2V0SW1hZ2VVcmwoc3JjOiBzdHJpbmcsIGZuPzogKCkgPT4gdm9pZCkge1xuICAgICAgICB0aGlzLmxvYWRJbWFnZShzcmMsIGZuKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9wb3NpdGlvbkltZyhjcm9wRXZlbnQ6IEltZ0Nyb3BwZXJFdmVudCwgZm4/OiAoKSA9PiB2b2lkKSB7XG4gICAgICAgIGNvbnN0IGxvYWRDb25maWcgPSB0aGlzLl9jdXJyZW50TG9hZENvbmZpZztcbiAgICAgICAgdGhpcy5fdXBkYXRlTWluU2NhbGUodGhpcy5faW1nQ2FudmFzLm5hdGl2ZUVsZW1lbnQpO1xuICAgICAgICB0aGlzLl91cGRhdGVNYXhTY2FsZSgpO1xuICAgICAgICB0aGlzLmlzTG9hZGVkID0gZmFsc2U7XG4gICAgICAgIGlmIChmbikge1xuICAgICAgICAgICAgZm4oKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChsb2FkQ29uZmlnLnNjYWxlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTY2FsZShsb2FkQ29uZmlnLnNjYWxlLCB0cnVlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTY2FsZSh0aGlzLm1pblNjYWxlLCB0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMucm90YXRlKGxvYWRDb25maWcucm90YXRpb24gfHwgMCk7XG4gICAgICAgICAgICB0aGlzLl91cGRhdGVBcmVhSWZOZWVkZWQoKTtcbiAgICAgICAgICAgIHRoaXMuX21hcmtGb3JDaGVjaygpO1xuICAgICAgICAgICAgdGhpcy5fbmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uZ1pvbmVcbiAgICAgICAgICAgICAgICAgICAgLm9uU3RhYmxlXG4gICAgICAgICAgICAgICAgICAgIC5hc09ic2VydmFibGUoKVxuICAgICAgICAgICAgICAgICAgICAucGlwZSh0YWtlKDEpLCB0YWtlVW50aWwodGhpcy5fZGVzdHJveSkpXG4gICAgICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxvYWRDb25maWcueE9yaWdpbiAhPSBudWxsICYmIGxvYWRDb25maWcueU9yaWdpbiAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVQb3NpdGlvbihsb2FkQ29uZmlnLnhPcmlnaW4sIGxvYWRDb25maWcueU9yaWdpbik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl91cGRhdGVBcmVhSWZOZWVkZWQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNMb2FkZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY3JvcElmQXV0b0Nyb3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX25nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX21hcmtGb3JDaGVjaygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVhZHkuZW1pdChjcm9wRXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgcm90YXRlKGRlZ3JlZXM6IG51bWJlcikge1xuICAgICAgICBsZXQgdmFsaWREZWdyZWVzID0gX25vcm1hbGl6ZURlZ3JlZXMoZGVncmVlcyk7XG4gICAgICAgIC8vIElmIG5lZ2F0aXZlIGNvbnZlcnQgdG8gcG9zaXRpdmVcbiAgICAgICAgaWYgKHZhbGlkRGVncmVlcyA8IDApIHtcbiAgICAgICAgICAgIHZhbGlkRGVncmVlcyArPSAzNjA7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmV3Um90YXRpb24gPSBfbm9ybWFsaXplRGVncmVlcygodGhpcy5fcm90YXRpb24gfHwgMCkgKyB2YWxpZERlZ3JlZXMpO1xuICAgICAgICBpZiAobmV3Um90YXRpb24gPT09IHRoaXMuX3JvdGF0aW9uKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGVncmVlc1JhZCA9IHZhbGlkRGVncmVlcyAqIE1hdGguUEkgLyAxODA7XG4gICAgICAgIGNvbnN0IGNhbnZhcyA9IHRoaXMuX2ltZ0NhbnZhcy5uYXRpdmVFbGVtZW50O1xuICAgICAgICBjb25zdCBjYW52YXNDbG9uID0gY3JlYXRlQ2FudmFzSW1nKGNhbnZhcyk7XG4gICAgICAgIGNvbnN0IGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIik7XG4gICAgICAgIHRoaXMuX3JvdGF0aW9uID0gbmV3Um90YXRpb247XG5cbiAgICAgICAgLy8gY2xlYXJcbiAgICAgICAgY3R4LmNsZWFyUmVjdCgwLCAwLCBjYW52YXNDbG9uLndpZHRoLCBjYW52YXNDbG9uLmhlaWdodCk7XG5cbiAgICAgICAgLy8gcm90YXRlIGNhbnZhcyBpbWFnZVxuICAgICAgICBjb25zdCB0cmFuc2Zvcm0gPSBgcm90YXRlKCR7dmFsaWREZWdyZWVzfWRlZykgc2NhbGUoJHsxIC8gdGhpcy5fc2NhbDNGaXh9KWA7XG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybU9yaWdpbiA9IGAke3RoaXMuX2ltZ1JlY3QueGN9cHggJHt0aGlzLl9pbWdSZWN0LnljfXB4IDBgO1xuICAgICAgICBjYW52YXMuc3R5bGUudHJhbnNmb3JtID0gdHJhbnNmb3JtO1xuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6IGRlcHJlY2F0aW9uXG4gICAgICAgIGNhbnZhcy5zdHlsZS53ZWJraXRUcmFuc2Zvcm0gPSB0cmFuc2Zvcm07XG4gICAgICAgIGNhbnZhcy5zdHlsZS50cmFuc2Zvcm1PcmlnaW4gPSB0cmFuc2Zvcm1PcmlnaW47XG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogZGVwcmVjYXRpb25cbiAgICAgICAgY2FudmFzLnN0eWxlLndlYmtpdFRyYW5zZm9ybU9yaWdpbiA9IHRyYW5zZm9ybU9yaWdpbjtcblxuICAgICAgICBjb25zdCB7IGxlZnQsIHRvcCB9ID0gY2FudmFzLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpIGFzIERPTVJlY3Q7XG5cbiAgICAgICAgLy8gc2F2ZSByZWN0XG4gICAgICAgIGNvbnN0IGNhbnZhc1JlY3QgPSBjYW52YXMuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICAgICAgLy8gcmVtb3ZlIHJvdGF0ZSBzdHlsZXNcbiAgICAgICAgY2FudmFzLnJlbW92ZUF0dHJpYnV0ZShcInN0eWxlXCIpO1xuXG4gICAgICAgIC8vIHNldCB3ICYgaFxuICAgICAgICBjb25zdCB3ID0gY2FudmFzUmVjdC53aWR0aDtcbiAgICAgICAgY29uc3QgaCA9IGNhbnZhc1JlY3QuaGVpZ2h0O1xuICAgICAgICBjdHguY2FudmFzLndpZHRoID0gdztcbiAgICAgICAgY3R4LmNhbnZhcy5oZWlnaHQgPSBoO1xuXG4gICAgICAgIC8vIGNsZWFyXG4gICAgICAgIGN0eC5jbGVhclJlY3QoMCwgMCwgdywgaCk7XG5cbiAgICAgICAgLy8gdHJhbnNsYXRlIGFuZCByb3RhdGVcbiAgICAgICAgY3R4LnRyYW5zbGF0ZSh3IC8gMiwgaCAvIDIpO1xuICAgICAgICBjdHgucm90YXRlKGRlZ3JlZXNSYWQpO1xuICAgICAgICBjdHguZHJhd0ltYWdlKGNhbnZhc0Nsb24sIC1jYW52YXNDbG9uLndpZHRoIC8gMiwgLWNhbnZhc0Nsb24uaGVpZ2h0IC8gMik7XG5cbiAgICAgICAgLy8gVXBkYXRlIG1pbiBzY2FsZVxuICAgICAgICB0aGlzLl91cGRhdGVNaW5TY2FsZShjYW52YXMpO1xuICAgICAgICB0aGlzLl91cGRhdGVNYXhTY2FsZSgpO1xuXG4gICAgICAgIC8vIHNldCB0aGUgbWluaW11bSBzY2FsZSwgb25seSBpZiBuZWNlc3NhcnlcbiAgICAgICAgaWYgKHRoaXMuc2NhbGUgPCB0aGlzLm1pblNjYWxlKSB7XG4gICAgICAgICAgICB0aGlzLnNldFNjYWxlKDAsIHRydWUpO1xuICAgICAgICB9IC8vICAgICAgICAgICAgICAgIOKGkSBubyBBdXRvQ3JvcFxuXG4gICAgICAgIGNvbnN0IHJvb3RSZWN0ID0gdGhpcy5fcm9vdFJlY3QoKTtcblxuICAgICAgICB0aGlzLl9zZXRTdHlsZXNGb3JDb250SW1nKHtcbiAgICAgICAgICAgIHg6IChsZWZ0IC0gcm9vdFJlY3QubGVmdCksXG4gICAgICAgICAgICB5OiAodG9wIC0gcm9vdFJlY3QudG9wKVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBrZWVwIGltYWdlIGluc2lkZSB0aGUgZnJhbWVcbiAgICAgICAgY29uc3Qgb3JpZ2luUG9zaXRpb24gPSB7Li4udGhpcy5faW1nUmVjdH07XG4gICAgICAgIHRoaXMub2Zmc2V0ID0ge1xuICAgICAgICAgICAgeDogb3JpZ2luUG9zaXRpb24ueCxcbiAgICAgICAgICAgIHk6IG9yaWdpblBvc2l0aW9uLnksXG4gICAgICAgICAgICBsZWZ0OiBvcmlnaW5Qb3NpdGlvbi54YyxcbiAgICAgICAgICAgIHRvcDogb3JpZ2luUG9zaXRpb24ueWNcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5fc2V0U3R5bGVzRm9yQ29udEltZyh7fSk7XG4gICAgICAgIHRoaXMuX3NpbXVsYXRlUG9pbnRlck1vdmUoKTtcblxuICAgICAgICB0aGlzLl9jcm9wSWZBdXRvQ3JvcCgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBfdXBkYXRlTWluU2NhbGUoY2FudmFzPzogSFRNTENhbnZhc0VsZW1lbnQpIHtcbiAgICAgICAgaWYgKCFjYW52YXMpIHtcbiAgICAgICAgICAgIGNhbnZhcyA9IHRoaXMuX2ltZ0NhbnZhcy5uYXRpdmVFbGVtZW50O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuY29uZmlnO1xuICAgICAgICBjb25zdCBtaW5TY2FsZSA9IChjb25maWcuZXh0cmFab29tT3V0ID8gTWF0aC5taW4gOiBNYXRoLm1heCkoXG4gICAgICAgICAgICBjb25maWcud2lkdGggLyBjYW52YXMud2lkdGgsXG4gICAgICAgICAgICBjb25maWcuaGVpZ2h0IC8gY2FudmFzLmhlaWdodCk7XG4gICAgICAgIHRoaXMuX21pblNjYWxlID0gbWluU2NhbGU7XG4gICAgICAgIHRoaXMubWluU2NhbGVDaGFuZ2UuZW1pdChtaW5TY2FsZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfdXBkYXRlTWF4U2NhbGUoKSB7XG4gICAgICAgIGNvbnN0IG1heFNjYWxlID0gKHRoaXMuY29uZmlnLndpZHRoIC8gdGhpcy5fcHJpbWFyeUFyZWFXaWR0aCk7XG4gICAgICAgIHRoaXMuX21heFNjYWxlID0gbWF4U2NhbGU7XG4gICAgICAgIHRoaXMubWF4U2NhbGVDaGFuZ2UuZW1pdChtYXhTY2FsZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVzaXplICYgY3JvcCBpbWFnZVxuICAgICAqL1xuICAgIHB1YmxpYyBjcm9wKGNvbmZpZz86IEltZ0Nyb3BwZXJDb25maWcpOiBJbWdDcm9wcGVyRXZlbnQge1xuICAgICAgICBjb25zdCBuZXdDb25maWcgPSBjb25maWdcbiAgICAgICAgICAgID8gbWVyZ2VEZWVwKHsgfSwgdGhpcy5jb25maWcgfHwgbmV3IEltZ0Nyb3BwZXJDb25maWcoKSwgY29uZmlnKSA6IHRoaXMuY29uZmlnO1xuICAgICAgICBjb25zdCBjcm9wRXZlbnQgPSB0aGlzLl9pbWdDcm9wKG5ld0NvbmZpZyk7XG4gICAgICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gICAgICAgIHJldHVybiBjcm9wRXZlbnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGRvY3MtcHJpdmF0ZVxuICAgICAqL1xuICAgIHByaXZhdGUgX2ltZ0Nyb3AobXlDb25maWc6IEltZ0Nyb3BwZXJDb25maWcpIHtcbiAgICAgICAgY29uc3QgY2FudmFzRWxlbWVudDogSFRNTENhbnZhc0VsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiY2FudmFzXCIpO1xuICAgICAgICBjb25zdCBhcmVhUmVjdCA9IHRoaXMuX2FyZWFDcm9wcGVyUmVjdCgpO1xuICAgICAgICBjb25zdCBjYW52YXNSZWN0ID0gdGhpcy5fY2FudmFzUmVjdCgpO1xuICAgICAgICBjb25zdCBzY2FsZUZpeCA9IHRoaXMuX3NjYWwzRml4O1xuICAgICAgICBjb25zdCBsZWZ0ID0gKGFyZWFSZWN0LmxlZnQgLSBjYW52YXNSZWN0LmxlZnQpIC8gc2NhbGVGaXg7XG4gICAgICAgIGNvbnN0IHRvcCA9IChhcmVhUmVjdC50b3AgLSBjYW52YXNSZWN0LnRvcCkgLyBzY2FsZUZpeDtcbiAgICAgICAgY29uc3QgeyBvdXRwdXQgfSA9IG15Q29uZmlnO1xuICAgICAgICBjb25zdCBjdXJyZW50SW1hZ2VMb2FkQ29uZmlnID0gdGhpcy5fY3VycmVudExvYWRDb25maWc7XG4gICAgICAgIGNvbnN0IGFyZWEgPSB7XG4gICAgICAgICAgICB3aWR0aDogbXlDb25maWcud2lkdGgsXG4gICAgICAgICAgICBoZWlnaHQ6IG15Q29uZmlnLmhlaWdodFxuICAgICAgICB9O1xuICAgICAgICBjYW52YXNFbGVtZW50LndpZHRoID0gYXJlYS53aWR0aCAvIHNjYWxlRml4O1xuICAgICAgICBjYW52YXNFbGVtZW50LmhlaWdodCA9IGFyZWEuaGVpZ2h0IC8gc2NhbGVGaXg7XG4gICAgICAgIGNvbnN0IGN0eCA9IGNhbnZhc0VsZW1lbnQuZ2V0Q29udGV4dChcIjJkXCIpO1xuICAgICAgICBpZiAobXlDb25maWcuZmlsbCkge1xuICAgICAgICAgICAgY3R4LmZpbGxTdHlsZSA9IG15Q29uZmlnLmZpbGw7XG4gICAgICAgICAgICBjdHguZmlsbFJlY3QoMCwgMCwgY2FudmFzRWxlbWVudC53aWR0aCwgY2FudmFzRWxlbWVudC5oZWlnaHQpO1xuICAgICAgICB9XG4gICAgICAgIGN0eC5kcmF3SW1hZ2UodGhpcy5faW1nQ2FudmFzLm5hdGl2ZUVsZW1lbnQsXG4gICAgICAgICAgICAtKGxlZnQpLCAtKHRvcCksXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGNhbnZhc0VsZW1lbnQ7XG4gICAgICAgIGlmIChteUNvbmZpZy5vdXRwdXQgPT09IEltZ1Jlc29sdXRpb24uRGVmYXVsdCkge1xuICAgICAgICAgICAgcmVzaXplQ2FudmFzKFxuICAgICAgICAgICAgICAgIHJlc3VsdCxcbiAgICAgICAgICAgICAgICB0aGlzLl9jb25maWdQcmltYXJ5LndpZHRoLFxuICAgICAgICAgICAgICAgIHRoaXMuX2NvbmZpZ1ByaW1hcnkuaGVpZ2h0KTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2Ygb3V0cHV0ID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICBpZiAob3V0cHV0LndpZHRoICYmIG91dHB1dC5oZWlnaHQpIHtcbiAgICAgICAgICAgICAgICByZXNpemVDYW52YXMocmVzdWx0LCBvdXRwdXQud2lkdGgsIG91dHB1dC5oZWlnaHQpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChvdXRwdXQud2lkdGgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdIZWlnaHQgPSBhcmVhLmhlaWdodCAqIG91dHB1dC53aWR0aCAvIGFyZWEud2lkdGg7XG4gICAgICAgICAgICAgICAgcmVzaXplQ2FudmFzKHJlc3VsdCwgb3V0cHV0LndpZHRoLCBuZXdIZWlnaHQpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChvdXRwdXQuaGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbmV3V2lkdGggPSBhcmVhLndpZHRoICogb3V0cHV0LmhlaWdodCAvIGFyZWEuaGVpZ2h0O1xuICAgICAgICAgICAgICAgIHJlc2l6ZUNhbnZhcyhyZXN1bHQsIG5ld1dpZHRoLCBvdXRwdXQuaGVpZ2h0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCB0eXBlID0gY3VycmVudEltYWdlTG9hZENvbmZpZy5vcmlnaW5hbERhdGFVUkwuc3RhcnRzV2l0aChcImh0dHBcIilcbiAgICAgICAgICAgID8gY3VycmVudEltYWdlTG9hZENvbmZpZy50eXBlIHx8IG15Q29uZmlnLnR5cGVcbiAgICAgICAgICAgIDogbXlDb25maWcudHlwZSB8fCBjdXJyZW50SW1hZ2VMb2FkQ29uZmlnLnR5cGU7XG4gICAgICAgIGNvbnN0IGRhdGFVUkwgPSByZXN1bHQudG9EYXRhVVJMKHR5cGUpO1xuICAgICAgICBjb25zdCBjcm9wRXZlbnQ6IEltZ0Nyb3BwZXJFdmVudCA9IHtcbiAgICAgICAgICAgIGRhdGFVUkwsXG4gICAgICAgICAgICB0eXBlLFxuICAgICAgICAgICAgbmFtZTogY3VycmVudEltYWdlTG9hZENvbmZpZy5uYW1lLFxuICAgICAgICAgICAgYXJlYVdpZHRoOiB0aGlzLl9wcmltYXJ5QXJlYVdpZHRoLFxuICAgICAgICAgICAgYXJlYUhlaWdodDogdGhpcy5fcHJpbWFyeUFyZWFIZWlnaHQsXG4gICAgICAgICAgICB3aWR0aDogcmVzdWx0LndpZHRoLFxuICAgICAgICAgICAgaGVpZ2h0OiByZXN1bHQuaGVpZ2h0LFxuICAgICAgICAgICAgb3JpZ2luYWxEYXRhVVJMOiBjdXJyZW50SW1hZ2VMb2FkQ29uZmlnLm9yaWdpbmFsRGF0YVVSTCxcbiAgICAgICAgICAgIHNjYWxlOiB0aGlzLl9hYnNvbHV0ZVNjYWxlLFxuICAgICAgICAgICAgcm90YXRpb246IHRoaXMuX3JvdGF0aW9uLFxuICAgICAgICAgICAgbGVmdDogKGFyZWFSZWN0LmxlZnQgLSBjYW52YXNSZWN0LmxlZnQpIC8gdGhpcy5fc2NhbDNGaXgsXG4gICAgICAgICAgICB0b3A6IChhcmVhUmVjdC50b3AgLSBjYW52YXNSZWN0LnRvcCkgLyB0aGlzLl9zY2FsM0ZpeCxcbiAgICAgICAgICAgIHNpemU6IGN1cnJlbnRJbWFnZUxvYWRDb25maWcuc2l6ZSxcbiAgICAgICAgICAgIHhPcmlnaW46IHRoaXMuX2ltZ1JlY3QueGMsXG4gICAgICAgICAgICB5T3JpZ2luOiB0aGlzLl9pbWdSZWN0LnljLFxuICAgICAgICAgICAgcG9zaXRpb246IHtcbiAgICAgICAgICAgICAgICB4OiB0aGlzLl9pbWdSZWN0LnhjLFxuICAgICAgICAgICAgICAgIHk6IHRoaXMuX2ltZ1JlY3QueWNcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLmlzQ3JvcHBlZCA9IHRydWU7XG4gICAgICAgIHRoaXMuY3JvcHBlZC5lbWl0KGNyb3BFdmVudCk7XG4gICAgICAgIHJldHVybiBjcm9wRXZlbnQ7XG4gICAgfVxuXG4gICAgcHVibGljIF9yb290UmVjdCgpOiBET01SZWN0IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSBhcyBET01SZWN0O1xuICAgIH1cblxuICAgIHB1YmxpYyBfYXJlYUNyb3BwZXJSZWN0KCk6IERPTVJlY3Qge1xuICAgICAgICByZXR1cm4gdGhpcy5fYXJlYVJlZi5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpIGFzIERPTVJlY3Q7XG4gICAgfVxuXG4gICAgcHVibGljIF9jYW52YXNSZWN0KCk6IERPTVJlY3Qge1xuICAgICAgICByZXR1cm4gdGhpcy5faW1nQ2FudmFzLm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgfVxuXG5cbiAgICAvKiogQ2FsbGVkIHdoZW4gdGhlIHVzZXIgaGFzIGxpZnRlZCB0aGVpciBwb2ludGVyLiAqL1xuICAgIHByaXZhdGUgX3BvaW50ZXJVcCA9IChldmVudDogVG91Y2hFdmVudCB8IE1vdXNlRXZlbnQpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuX2lzU2xpZGluZykge1xuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIHRoaXMuX3JlbW92ZUdsb2JhbEV2ZW50cygpO1xuICAgICAgICAgICAgdGhpcy5faXNTbGlkaW5nID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLl9zdGFydFBvaW50ZXJFdmVudCA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLl9jcm9wSWZBdXRvQ3JvcCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIENhbGxlZCB3aGVuIHRoZSB3aW5kb3cgaGFzIGxvc3QgZm9jdXMuICovXG4gICAgcHJpdmF0ZSBfd2luZG93Qmx1ciA9ICgpID0+IHtcbiAgICAgICAgLy8gSWYgdGhlIHdpbmRvdyBpcyBibHVycmVkIHdoaWxlIGRyYWdnaW5nIHdlIG5lZWQgdG8gc3RvcCBkcmFnZ2luZyBiZWNhdXNlIHRoZVxuICAgICAgICAvLyBicm93c2VyIHdvbid0IGRpc3BhdGNoIHRoZSBgbW91c2V1cGAgYW5kIGB0b3VjaGVuZGAgZXZlbnRzIGFueW1vcmUuXG4gICAgICAgIGlmICh0aGlzLl9sYXN0UG9pbnRlckV2ZW50KSB7XG4gICAgICAgICAgICB0aGlzLl9wb2ludGVyVXAodGhpcy5fbGFzdFBvaW50ZXJFdmVudCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIF9iaW5kR2xvYmFsRXZlbnRzKHRyaWdnZXJFdmVudDogVG91Y2hFdmVudCB8IE1vdXNlRXZlbnQpIHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuX2RvY3VtZW50O1xuICAgICAgICBjb25zdCBpc1RvdWNoID0gaXNUb3VjaEV2ZW50KHRyaWdnZXJFdmVudCk7XG4gICAgICAgIGNvbnN0IG1vdmVFdmVudE5hbWUgPSBpc1RvdWNoID8gXCJ0b3VjaG1vdmVcIiA6IFwibW91c2Vtb3ZlXCI7XG4gICAgICAgIGNvbnN0IGVuZEV2ZW50TmFtZSA9IGlzVG91Y2ggPyBcInRvdWNoZW5kXCIgOiBcIm1vdXNldXBcIjtcbiAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKG1vdmVFdmVudE5hbWUsIHRoaXMuX3BvaW50ZXJNb3ZlLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoZW5kRXZlbnROYW1lLCB0aGlzLl9wb2ludGVyVXAsIGFjdGl2ZUV2ZW50T3B0aW9ucyk7XG5cbiAgICAgICAgaWYgKGlzVG91Y2gpIHtcbiAgICAgICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNoY2FuY2VsXCIsIHRoaXMuX3BvaW50ZXJVcCwgYWN0aXZlRXZlbnRPcHRpb25zKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHdpbmRvdyA9IHRoaXMuX2dldFdpbmRvdygpO1xuXG4gICAgICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiICYmIHdpbmRvdykge1xuICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJibHVyXCIsIHRoaXMuX3dpbmRvd0JsdXIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIFJlbW92ZXMgYW55IGdsb2JhbCBldmVudCBsaXN0ZW5lcnMgdGhhdCB3ZSBtYXkgaGF2ZSBhZGRlZC4gKi9cbiAgICBwcml2YXRlIF9yZW1vdmVHbG9iYWxFdmVudHMoKSB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLl9kb2N1bWVudDtcbiAgICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2Vtb3ZlXCIsIHRoaXMuX3BvaW50ZXJNb3ZlLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtb3VzZXVwXCIsIHRoaXMuX3BvaW50ZXJVcCwgYWN0aXZlRXZlbnRPcHRpb25zKTtcbiAgICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2htb3ZlXCIsIHRoaXMuX3BvaW50ZXJNb3ZlLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ0b3VjaGVuZFwiLCB0aGlzLl9wb2ludGVyVXAsIGFjdGl2ZUV2ZW50T3B0aW9ucyk7XG4gICAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRvdWNoY2FuY2VsXCIsIHRoaXMuX3BvaW50ZXJVcCwgYWN0aXZlRXZlbnRPcHRpb25zKTtcblxuICAgICAgICBjb25zdCB3aW5kb3cgPSB0aGlzLl9nZXRXaW5kb3coKTtcblxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJiB3aW5kb3cpIHtcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFwiYmx1clwiLCB0aGlzLl93aW5kb3dCbHVyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBVc2UgZGVmYXVsdFZpZXcgb2YgaW5qZWN0ZWQgZG9jdW1lbnQgaWYgYXZhaWxhYmxlIG9yIGZhbGxiYWNrIHRvIGdsb2JhbCB3aW5kb3cgcmVmZXJlbmNlICovXG4gICAgcHJpdmF0ZSBfZ2V0V2luZG93KCk6IFdpbmRvdyB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kb2N1bWVudC5kZWZhdWx0VmlldyB8fCB3aW5kb3c7XG4gICAgfVxuXG59XG5cbi8qKlxuICogTm9ybWFsaXplIGRlZ3JlZXMgZm9yIGNyb3BwZXIgcm90YXRpb25cbiAqIEBkb2NzLXByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9ub3JtYWxpemVEZWdyZWVzKG46IG51bWJlcikge1xuICAgIGNvbnN0IGRlID0gbiAlIDM2MDtcbiAgICBpZiAoZGUgJSA5MCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEx5Q3JvcHBlcjogSW52YWxpZCBcXGAke259XFxgIGRlZ3JlZSwgb25seSBhY2NlcHRlZCB2YWx1ZXM6IDAsIDkwLCAxODAsIDI3MCAmIDM2MC5gKTtcbiAgICB9XG4gICAgcmV0dXJuIGRlO1xufVxuXG4vKipcbiAqIEBkb2NzLXByaXZhdGVcbiAqL1xuZnVuY3Rpb24gY3JlYXRlQ2FudmFzSW1nKGltZzogSFRNTENhbnZhc0VsZW1lbnQgfCBIVE1MSW1hZ2VFbGVtZW50KSB7XG5cbiAgICAvLyBjcmVhdGUgYSBuZXcgY2FudmFzXG4gICAgY29uc3QgbmV3Q2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgICBjb25zdCBjb250ZXh0ID0gbmV3Q2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcblxuICAgIC8vIHNldCBkaW1lbnNpb25zXG4gICAgbmV3Q2FudmFzLndpZHRoID0gaW1nLndpZHRoO1xuICAgIG5ld0NhbnZhcy5oZWlnaHQgPSBpbWcuaGVpZ2h0O1xuXG4gICAgLy8gYXBwbHkgdGhlIG9sZCBjYW52YXMgdG8gdGhlIG5ldyBvbmVcbiAgICBjb250ZXh0LmRyYXdJbWFnZShpbWcsIDAsIDApO1xuXG4gICAgLy8gcmV0dXJuIHRoZSBuZXcgY2FudmFzXG4gICAgcmV0dXJuIG5ld0NhbnZhcztcbn1cblxuXG5jb25zdCBEQVRBX0lNQUdFX1NWR19QUkVGSVggPSBcImRhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsXCI7XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZVNWRyhkYXRhVVJMOiBzdHJpbmcpIHtcbiAgICBpZiAod2luZG93LmF0b2IgJiYgaXNTdmdJbWFnZShkYXRhVVJMKSkge1xuICAgICAgICBjb25zdCBsZW4gPSBkYXRhVVJMLmxlbmd0aCAvIDU7XG4gICAgICAgIGNvbnN0IHRleHQgPSB3aW5kb3cuYXRvYihkYXRhVVJMLnJlcGxhY2UoREFUQV9JTUFHRV9TVkdfUFJFRklYLCBcIlwiKSk7XG4gICAgICAgIGNvbnN0IHNwYW4gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3BhblwiKTtcbiAgICAgICAgc3Bhbi5pbm5lckhUTUwgPSB0ZXh0O1xuICAgICAgICBjb25zdCBzdmcgPSBzcGFuLnF1ZXJ5U2VsZWN0b3IoXCJzdmdcIik7XG4gICAgICAgIHNwYW4uc2V0QXR0cmlidXRlKFwic3R5bGVcIiwgXCJkaXNwbGF5Om5vbmVcIik7XG4gICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoc3Bhbik7XG4gICAgICAgIGNvbnN0IHdpZHRoID0gcGFyc2VGbG9hdChnZXRDb21wdXRlZFN0eWxlKHN2Zykud2lkdGgpIHx8IDE7XG4gICAgICAgIGNvbnN0IGhlaWdodCA9IHBhcnNlRmxvYXQoZ2V0Q29tcHV0ZWRTdHlsZShzdmcpLmhlaWdodCkgfHwgMTtcbiAgICAgICAgY29uc3QgbWF4ID0gTWF0aC5tYXgod2lkdGgsIGhlaWdodCk7XG5cbiAgICAgICAgc3ZnLnNldEF0dHJpYnV0ZShcIndpZHRoXCIsIGAke2xlbiAvICh3aWR0aCAvIG1heCl9cHhgKTtcbiAgICAgICAgc3ZnLnNldEF0dHJpYnV0ZShcImhlaWdodFwiLCBgJHtsZW4gLyAoaGVpZ2h0IC8gbWF4KX1weGApO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBEQVRBX0lNQUdFX1NWR19QUkVGSVggKyB3aW5kb3cuYnRvYShzcGFuLmlubmVySFRNTCk7XG4gICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoc3Bhbik7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIHJldHVybiBkYXRhVVJMO1xufVxuXG5mdW5jdGlvbiBpc1N2Z0ltYWdlKGRhdGFVcmw6IHN0cmluZykge1xuICAgIHJldHVybiBkYXRhVXJsLnN0YXJ0c1dpdGgoREFUQV9JTUFHRV9TVkdfUFJFRklYKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlSHRtbEltZyhzcmM6IHN0cmluZykge1xuICAgIGNvbnN0IGltZyA9IG5ldyBJbWFnZSgpO1xuICAgIGltZy5jcm9zc09yaWdpbiA9IFwiYW5vbnltb3VzXCI7XG4gICAgaW1nLnNyYyA9IHNyYztcbiAgICByZXR1cm4gaW1nO1xufVxuXG5cbmZ1bmN0aW9uIGdldEdlc3R1cmVQb2ludEZyb21FdmVudChldmVudDogVG91Y2hFdmVudCB8IE1vdXNlRXZlbnQpIHtcblxuICAgIC8vIGB0b3VjaGVzYCB3aWxsIGJlIGVtcHR5IGZvciBzdGFydC9lbmQgZXZlbnRzIHNvIHdlIGhhdmUgdG8gZmFsbCBiYWNrIHRvIGBjaGFuZ2VkVG91Y2hlc2AuXG4gICAgY29uc3QgcG9pbnQgPSBpc1RvdWNoRXZlbnQoZXZlbnQpXG4gICAgICAgID8gKGV2ZW50LnRvdWNoZXNbMF0gfHwgZXZlbnQuY2hhbmdlZFRvdWNoZXNbMF0pXG4gICAgICAgIDogZXZlbnQ7XG5cbiAgICByZXR1cm4ge1xuICAgICAgICB4OiBwb2ludC5jbGllbnRYLFxuICAgICAgICB5OiBwb2ludC5jbGllbnRZXG4gICAgfTtcbn1cblxuLyoqIFJldHVybnMgd2hldGhlciBhbiBldmVudCBpcyBhIHRvdWNoIGV2ZW50LiAqL1xuZnVuY3Rpb24gaXNUb3VjaEV2ZW50KGV2ZW50OiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCk6IGV2ZW50IGlzIFRvdWNoRXZlbnQge1xuICAgIHJldHVybiBldmVudC50eXBlWzBdID09PSBcInRcIjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJvdW5kKG46IG51bWJlcikge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKG4pO1xufVxuXG4vKipcbiAqIFNpbXBsZSBvYmplY3QgY2hlY2suXG4gKiBAcGFyYW0gaXRlbVxuICovXG5mdW5jdGlvbiBpc09iamVjdChpdGVtKSB7XG4gICAgcmV0dXJuIChpdGVtICYmIHR5cGVvZiBpdGVtID09PSBcIm9iamVjdFwiICYmICFBcnJheS5pc0FycmF5KGl0ZW0pKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlRGVlcDxULCBVPih0YXJnZXQ6IFQsIHNvdXJjZTogVSk6IFQgJiBVO1xuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlRGVlcDxULCBVLCBWPih0YXJnZXQ6IFQsIHNvdXJjZTE6IFUsIHNvdXJjZTI6IFYpOiBUICYgVSAmIFY7XG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VEZWVwPFQsIFUsIFYsIFc+KHRhcmdldDogVCwgc291cmNlMTogVSwgc291cmNlMjogViwgc291cmNlMzogVyk6IFQgJiBVICYgViAmIFc7XG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VEZWVwKHRhcmdldDogb2JqZWN0LCAuLi5zb3VyY2VzOiBhbnlbXSk6IGFueTtcblxuLyoqXG4gKiBEZWVwIG1lcmdlIHR3byBvYmplY3RzLlxuICogQHBhcmFtIHRhcmdldFxuICogQHBhcmFtIC4uLnNvdXJjZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlRGVlcCh0YXJnZXQ6IGFueSwgLi4uc291cmNlczogYW55W10pIHtcbiAgICBpZiAoIXNvdXJjZXMubGVuZ3RoKSB7IHJldHVybiB0YXJnZXQ7IH1cbiAgICBjb25zdCBzb3VyY2UgPSBzb3VyY2VzLnNoaWZ0KCk7XG5cbiAgICBpZiAoaXNPYmplY3QodGFyZ2V0KSAmJiBpc09iamVjdChzb3VyY2UpKSB7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIHNvdXJjZSkge1xuICAgICAgICAgICAgaWYgKGlzT2JqZWN0KHNvdXJjZVtrZXldKSkge1xuICAgICAgICAgICAgICAgIGlmICghdGFyZ2V0W2tleV0pIHsgT2JqZWN0LmFzc2lnbih0YXJnZXQsIHsgW2tleV06IHt9IH0pOyB9XG4gICAgICAgICAgICAgICAgbWVyZ2VEZWVwKHRhcmdldFtrZXldLCBzb3VyY2Vba2V5XSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIE9iamVjdC5hc3NpZ24odGFyZ2V0LCB7IFtrZXldOiBzb3VyY2Vba2V5XSB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBtZXJnZURlZXAodGFyZ2V0LCAuLi5zb3VyY2VzKTtcbn1cblxuXG4vKipcbiAqIFdlIGhhdmUgdGhlIGNyb3BwZXIgYXJlYSBpbiB0aGUgc2FtZSBmaWxlIHRvIGZpeCB0aGUgYnVpbGRcbiAqL1xuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogXCJuaWNlLWNyb3BwZXItYXJlYVwiLFxuICAgIHRlbXBsYXRlVXJsOiBcIi4vaW1hZ2UtY3JvcHBlci1hcmVhLnRlbXBsYXRlLmh0bWxcIixcbiAgICBzdHlsZVVybHM6IFtcIi4vaW1hZ2UtY3JvcHBlci1hcmVhLnN0eWxlLnNjc3NcIl0sXG4gICAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBOaWNlQ3JvcHBlckFyZWFDb21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICAgIEBWaWV3Q2hpbGQoXCJyZXNpemVyXCIpXG4gICAgcHJpdmF0ZSByZWFkb25seSBfcmVzaXplcj86IEVsZW1lbnRSZWY7XG5cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBrZWVwQXNwZWN0UmF0aW86IGJvb2xlYW47XG5cbiAgICBASW5wdXQoKVxuICAgIEBIb3N0QmluZGluZyhcImNsYXNzLnJvdW5kXCIpXG4gICAgcHVibGljIHJvdW5kOiBib29sZWFuO1xuXG4gICAgLyoqIFVzZWQgdG8gc3Vic2NyaWJlIHRvIGdsb2JhbCBtb3ZlIGFuZCBlbmQgZXZlbnRzICovXG4gICAgcHJvdGVjdGVkIF9kb2N1bWVudDogRG9jdW1lbnQ7XG4gICAgcHJpdmF0ZSBfaXNTbGlkaW5nOiBib29sZWFuO1xuXG4gICAgLyoqIEtlZXBzIHRyYWNrIG9mIHRoZSBsYXN0IHBvaW50ZXIgZXZlbnQgdGhhdCB3YXMgY2FwdHVyZWQgYnkgdGhlIGNyb3AgYXJlYS4gKi9cbiAgICBwcml2YXRlIF9sYXN0UG9pbnRlckV2ZW50OiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCB8IG51bGw7XG4gICAgcHJpdmF0ZSBfc3RhcnRQb2ludGVyRXZlbnQ6IHtcbiAgICAgICAgeDogbnVtYmVyXG4gICAgICAgIHk6IG51bWJlclxuICAgIH0gfCBudWxsO1xuICAgIHByaXZhdGUgX2N1cnJlbnRXaWR0aDogbnVtYmVyO1xuICAgIHByaXZhdGUgX2N1cnJlbnRIZWlnaHQ6IG51bWJlcjtcbiAgICBwcml2YXRlIF9zdGFydEFyZWFSZWN0OiBET01SZWN0O1xuICAgIHByaXZhdGUgX3N0YXJ0SW1nUmVjdDogRE9NUmVjdDtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBASW5qZWN0KERPQ1VNRU5UKSBfZG9jdW1lbnQ6IGFueSxcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBfZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBfY3JvcHBlcjogTmljZUltYWdlQ3JvcHBlckNvbXBvbmVudCxcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBfbmdab25lOiBOZ1pvbmUsXG4gICAgKSB7XG4gICAgICAgIHRoaXMuX2RvY3VtZW50ID0gX2RvY3VtZW50O1xuICAgIH1cblxuICAgIHByaXZhdGUgX3Jlc2l6YWJsZUFyZWE6IGJvb2xlYW47XG5cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBzZXQgcmVzaXphYmxlQXJlYSh2YWw6IGJvb2xlYW4pIHtcbiAgICAgICAgaWYgKHZhbCAhPT0gdGhpcy5fcmVzaXphYmxlQXJlYSkge1xuICAgICAgICAgICAgdGhpcy5fcmVzaXphYmxlQXJlYSA9IHZhbDtcbiAgICAgICAgICAgIFByb21pc2UucmVzb2x2ZShudWxsKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodmFsKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3JlbW92ZVJlc2l6YWJsZUFyZWEoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYWRkUmVzaXphYmxlQXJlYSgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3JlbW92ZVJlc2l6YWJsZUFyZWEoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBwdWJsaWMgZ2V0IHJlc2l6YWJsZUFyZWEoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yZXNpemFibGVBcmVhO1xuICAgIH1cblxuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5fcmVtb3ZlUmVzaXphYmxlQXJlYSgpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX2FkZFJlc2l6YWJsZUFyZWEoKSB7XG4gICAgICAgIHRoaXMuX25nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5fcmVzaXplci5uYXRpdmVFbGVtZW50O1xuICAgICAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwibW91c2Vkb3duXCIsIHRoaXMuX3BvaW50ZXJEb3duLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgICAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hzdGFydFwiLCB0aGlzLl9wb2ludGVyRG93biwgYWN0aXZlRXZlbnRPcHRpb25zKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcmVtb3ZlUmVzaXphYmxlQXJlYSgpIHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuX3Jlc2l6ZXI/Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgIGlmIChlbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLl9sYXN0UG9pbnRlckV2ZW50ID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX3JlbW92ZUdsb2JhbEV2ZW50cygpO1xuICAgICAgICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2Vkb3duXCIsIHRoaXMuX3BvaW50ZXJEb3duLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgICAgICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2hzdGFydFwiLCB0aGlzLl9wb2ludGVyRG93biwgYWN0aXZlRXZlbnRPcHRpb25zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgX3BvaW50ZXJEb3duID0gKGV2ZW50OiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCkgPT4ge1xuICAgICAgICAvLyBEb24ndCBkbyBhbnl0aGluZyBpZiB0aGVcbiAgICAgICAgLy8gdXNlciBpcyB1c2luZyBhbnl0aGluZyBvdGhlciB0aGFuIHRoZSBtYWluIG1vdXNlIGJ1dHRvbi5cbiAgICAgICAgaWYgKHRoaXMuX2lzU2xpZGluZyB8fCAoIWlzVG91Y2hFdmVudChldmVudCkgJiYgZXZlbnQuYnV0dG9uICE9PSAwKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICB0aGlzLl9uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX2lzU2xpZGluZyA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLl9sYXN0UG9pbnRlckV2ZW50ID0gZXZlbnQ7XG4gICAgICAgICAgICB0aGlzLl9zdGFydFBvaW50ZXJFdmVudCA9IGdldEdlc3R1cmVQb2ludEZyb21FdmVudChldmVudCk7XG4gICAgICAgICAgICB0aGlzLl9zdGFydEFyZWFSZWN0ID0gdGhpcy5fY3JvcHBlci5fYXJlYUNyb3BwZXJSZWN0KCk7XG4gICAgICAgICAgICB0aGlzLl9zdGFydEltZ1JlY3QgPSB0aGlzLl9jcm9wcGVyLl9jYW52YXNSZWN0KCk7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgdGhpcy5fYmluZEdsb2JhbEV2ZW50cyhldmVudCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3BvaW50ZXJNb3ZlID0gKGV2ZW50OiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5faXNTbGlkaW5nKSB7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgdGhpcy5fbGFzdFBvaW50ZXJFdmVudCA9IGV2ZW50O1xuICAgICAgICAgICAgY29uc3QgZWxlbWVudDogSFRNTERpdkVsZW1lbnQgPSB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgICAgICBjb25zdCB7d2lkdGgsIGhlaWdodCwgbWluV2lkdGgsIG1pbkhlaWdodH0gPSB0aGlzLl9jcm9wcGVyLmNvbmZpZztcbiAgICAgICAgICAgIGNvbnN0IHBvaW50ID0gZ2V0R2VzdHVyZVBvaW50RnJvbUV2ZW50KGV2ZW50KTtcbiAgICAgICAgICAgIGNvbnN0IGRlbHRhWCA9IHBvaW50LnggLSB0aGlzLl9zdGFydFBvaW50ZXJFdmVudC54O1xuICAgICAgICAgICAgY29uc3QgZGVsdGFZID0gcG9pbnQueSAtIHRoaXMuX3N0YXJ0UG9pbnRlckV2ZW50Lnk7XG4gICAgICAgICAgICBjb25zdCBzdGFydEFyZWFSZWN0ID0gdGhpcy5fc3RhcnRBcmVhUmVjdDtcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0SW1nUmVjdCA9IHRoaXMuX3N0YXJ0SW1nUmVjdDtcbiAgICAgICAgICAgIGNvbnN0IGlzUm91bmQgPSB0aGlzLnJvdW5kO1xuICAgICAgICAgICAgY29uc3Qga2VlcEFzcGVjdFJhdGlvID0gdGhpcy5fY3JvcHBlci5jb25maWcua2VlcEFzcGVjdFJhdGlvIHx8IGV2ZW50LnNoaWZ0S2V5O1xuICAgICAgICAgICAgbGV0IG5ld1dpZHRoID0gMDtcbiAgICAgICAgICAgIGxldCBuZXdIZWlnaHQgPSAwO1xuICAgICAgICAgICAgY29uc3Qgcm9vdFJlY3QgPSB0aGlzLl9jcm9wcGVyLl9yb290UmVjdCgpO1xuXG4gICAgICAgICAgICBpZiAoaXNSb3VuZCkge1xuICAgICAgICAgICAgICAgIC8vIFRoZSBkaXN0YW5jZSBmcm9tIHRoZSBjZW50ZXIgb2YgdGhlIGNyb3BwZXIgYXJlYSB0byB0aGUgcG9pbnRlclxuICAgICAgICAgICAgICAgIGNvbnN0IG9yaWdpblggPSAoKHdpZHRoIC8gMiAvIE1hdGguc3FydCgyKSkgKyBkZWx0YVgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IG9yaWdpblkgPSAoKGhlaWdodCAvIDIgLyBNYXRoLnNxcnQoMikpICsgZGVsdGFZKTtcblxuICAgICAgICAgICAgICAgIC8vIExlZ1xuICAgICAgICAgICAgICAgIGNvbnN0IHNpZGUgPSBNYXRoLnNxcnQob3JpZ2luWCAqKiAyICsgb3JpZ2luWSAqKiAyKTtcbiAgICAgICAgICAgICAgICBuZXdXaWR0aCA9IG5ld0hlaWdodCA9IHNpZGUgKiAyO1xuXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGtlZXBBc3BlY3RSYXRpbykge1xuICAgICAgICAgICAgICAgIG5ld1dpZHRoID0gd2lkdGggKyBkZWx0YVggKiAyO1xuICAgICAgICAgICAgICAgIG5ld0hlaWdodCA9IGhlaWdodCArIGRlbHRhWSAqIDI7XG4gICAgICAgICAgICAgICAgaWYgKHdpZHRoICE9PSBoZWlnaHQpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHdpZHRoID4gaGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdIZWlnaHQgPSBoZWlnaHQgLyAod2lkdGggLyBuZXdXaWR0aCk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaGVpZ2h0ID4gd2lkdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1dpZHRoID0gd2lkdGggLyAoaGVpZ2h0IC8gbmV3SGVpZ2h0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIG5ld1dpZHRoID0gbmV3SGVpZ2h0ID0gTWF0aC5tYXgobmV3V2lkdGgsIG5ld0hlaWdodCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBuZXdXaWR0aCA9IHdpZHRoICsgZGVsdGFYICogMjtcbiAgICAgICAgICAgICAgICBuZXdIZWlnaHQgPSBoZWlnaHQgKyBkZWx0YVkgKiAyO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBUbyBtaW4gd2lkdGhcbiAgICAgICAgICAgIGlmIChuZXdXaWR0aCA8IG1pbldpZHRoKSB7XG4gICAgICAgICAgICAgICAgbmV3V2lkdGggPSBtaW5XaWR0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFRvIG1pbiBoZWlnaHRcbiAgICAgICAgICAgIGlmIChuZXdIZWlnaHQgPCBtaW5IZWlnaHQpIHtcbiAgICAgICAgICAgICAgICBuZXdIZWlnaHQgPSBtaW5IZWlnaHQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIERvIG5vdCBvdmVyZmxvdyB0aGUgY3JvcHBlciBhcmVhXG4gICAgICAgICAgICBjb25zdCBjZW50ZXJYID0gc3RhcnRBcmVhUmVjdC54ICsgc3RhcnRBcmVhUmVjdC53aWR0aCAvIDI7XG4gICAgICAgICAgICBjb25zdCBjZW50ZXJZID0gc3RhcnRBcmVhUmVjdC55ICsgc3RhcnRBcmVhUmVjdC5oZWlnaHQgLyAyO1xuICAgICAgICAgICAgY29uc3QgdG9wT3ZlcmZsb3cgPSBzdGFydEltZ1JlY3QueSA+IGNlbnRlclkgLSAobmV3SGVpZ2h0IC8gMik7XG4gICAgICAgICAgICBjb25zdCBib3R0b21PdmVyZmxvdyA9IGNlbnRlclkgKyAobmV3SGVpZ2h0IC8gMikgPiBzdGFydEltZ1JlY3QuYm90dG9tO1xuICAgICAgICAgICAgY29uc3QgbWluSGVpZ2h0T25PdmVyZmxvdyA9IE1hdGgubWluKChjZW50ZXJZIC0gc3RhcnRJbWdSZWN0LnkpICogMiwgKHN0YXJ0SW1nUmVjdC5ib3R0b20gLSBjZW50ZXJZKSAqIDIpO1xuICAgICAgICAgICAgY29uc3QgbGVmdE92ZXJmbG93ID0gc3RhcnRJbWdSZWN0LnggPiBjZW50ZXJYIC0gKG5ld1dpZHRoIC8gMik7XG4gICAgICAgICAgICBjb25zdCByaWdodE92ZXJmbG93ID0gY2VudGVyWCArIChuZXdXaWR0aCAvIDIpID4gc3RhcnRJbWdSZWN0LnJpZ2h0O1xuICAgICAgICAgICAgY29uc3QgbWluV2lkdGhPbk92ZXJmbG93ID0gTWF0aC5taW4oKGNlbnRlclggLSBzdGFydEltZ1JlY3QueCkgKiAyLCAoc3RhcnRJbWdSZWN0LnJpZ2h0IC0gY2VudGVyWCkgKiAyKTtcbiAgICAgICAgICAgIGNvbnN0IG1pbk9uT3ZlcmZsb3cgPSBNYXRoLm1pbihtaW5XaWR0aE9uT3ZlcmZsb3csIG1pbkhlaWdodE9uT3ZlcmZsb3cpO1xuICAgICAgICAgICAgaWYgKHJvdW5kKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRvcE92ZXJmbG93IHx8IGJvdHRvbU92ZXJmbG93IHx8IGxlZnRPdmVyZmxvdyB8fCByaWdodE92ZXJmbG93KSB7XG4gICAgICAgICAgICAgICAgICAgIG5ld0hlaWdodCA9IG5ld1dpZHRoID0gbWluT25PdmVyZmxvdztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGtlZXBBc3BlY3RSYXRpbykge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld05ld1dpZHRoOiBudW1iZXJbXSA9IFtdO1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld05ld0hlaWdodDogbnVtYmVyW10gPSBbXTtcbiAgICAgICAgICAgICAgICBpZiAoKHRvcE92ZXJmbG93IHx8IGJvdHRvbU92ZXJmbG93KSAmJiBNYXRoLm1pbigpKSB7XG4gICAgICAgICAgICAgICAgICAgIG5ld0hlaWdodCA9IG1pbkhlaWdodE9uT3ZlcmZsb3c7XG4gICAgICAgICAgICAgICAgICAgIG5ld05ld0hlaWdodC5wdXNoKG5ld0hlaWdodCk7XG4gICAgICAgICAgICAgICAgICAgIG5ld1dpZHRoID0gd2lkdGggLyAoaGVpZ2h0IC8gbWluSGVpZ2h0T25PdmVyZmxvdyk7XG4gICAgICAgICAgICAgICAgICAgIG5ld05ld1dpZHRoLnB1c2gobmV3V2lkdGgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoKGxlZnRPdmVyZmxvdyB8fCByaWdodE92ZXJmbG93KSkge1xuICAgICAgICAgICAgICAgICAgICBuZXdXaWR0aCA9IG1pbldpZHRoT25PdmVyZmxvdztcbiAgICAgICAgICAgICAgICAgICAgbmV3TmV3V2lkdGgucHVzaChuZXdXaWR0aCk7XG4gICAgICAgICAgICAgICAgICAgIG5ld0hlaWdodCA9IGhlaWdodCAvICh3aWR0aCAvIG1pbldpZHRoT25PdmVyZmxvdyk7XG4gICAgICAgICAgICAgICAgICAgIG5ld05ld0hlaWdodC5wdXNoKG5ld0hlaWdodCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChuZXdOZXdXaWR0aC5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3V2lkdGggPSBNYXRoLm1pbiguLi5uZXdOZXdXaWR0aCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChuZXdOZXdIZWlnaHQubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgICAgICAgICAgIG5ld0hlaWdodCA9IE1hdGgubWluKC4uLm5ld05ld0hlaWdodCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAodG9wT3ZlcmZsb3cgfHwgYm90dG9tT3ZlcmZsb3cpIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3SGVpZ2h0ID0gbWluSGVpZ2h0T25PdmVyZmxvdztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGxlZnRPdmVyZmxvdyB8fCByaWdodE92ZXJmbG93KSB7XG4gICAgICAgICAgICAgICAgICAgIG5ld1dpZHRoID0gbWluV2lkdGhPbk92ZXJmbG93O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRG8gbm90IG92ZXJmbG93IHRoZSBjb250YWluZXJcbiAgICAgICAgICAgIGlmIChyb3VuZCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1pbiA9IE1hdGgubWluKHJvb3RSZWN0LndpZHRoLCByb290UmVjdC5oZWlnaHQpO1xuICAgICAgICAgICAgICAgIGlmIChuZXdXaWR0aCA+IG1pbikge1xuICAgICAgICAgICAgICAgICAgICBuZXdXaWR0aCA9IG5ld0hlaWdodCA9IG1pbjtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5ld0hlaWdodCA+IG1pbikge1xuICAgICAgICAgICAgICAgICAgICBuZXdXaWR0aCA9IG5ld0hlaWdodCA9IG1pbjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGtlZXBBc3BlY3RSYXRpbykge1xuICAgICAgICAgICAgICAgIGlmIChuZXdXaWR0aCA+IHJvb3RSZWN0LndpZHRoKSB7XG4gICAgICAgICAgICAgICAgICAgIG5ld1dpZHRoID0gcm9vdFJlY3Qud2lkdGg7XG4gICAgICAgICAgICAgICAgICAgIG5ld0hlaWdodCA9IGhlaWdodCAvICh3aWR0aCAvIHJvb3RSZWN0LndpZHRoKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5ld0hlaWdodCA+IHJvb3RSZWN0LmhlaWdodCkge1xuICAgICAgICAgICAgICAgICAgICBuZXdXaWR0aCA9IHdpZHRoIC8gKGhlaWdodCAvIHJvb3RSZWN0LmhlaWdodCk7XG4gICAgICAgICAgICAgICAgICAgIG5ld0hlaWdodCA9IHJvb3RSZWN0LmhlaWdodDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChuZXdXaWR0aCA+IHJvb3RSZWN0LndpZHRoKSB7XG4gICAgICAgICAgICAgICAgICAgIG5ld1dpZHRoID0gcm9vdFJlY3Qud2lkdGg7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChuZXdIZWlnaHQgPiByb290UmVjdC5oZWlnaHQpIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3SGVpZ2h0ID0gcm9vdFJlY3QuaGVpZ2h0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuXG4gICAgICAgICAgICAvLyByb3VuZCB2YWx1ZXNcbiAgICAgICAgICAgIG5ld1dpZHRoID0gTWF0aC5yb3VuZChuZXdXaWR0aCk7XG4gICAgICAgICAgICBuZXdIZWlnaHQgPSBNYXRoLnJvdW5kKG5ld0hlaWdodCk7XG5cbiAgICAgICAgICAgIGVsZW1lbnQuc3R5bGUud2lkdGggPSBgJHtuZXdXaWR0aH1weGA7XG4gICAgICAgICAgICBlbGVtZW50LnN0eWxlLmhlaWdodCA9IGAke25ld0hlaWdodH1weGA7XG4gICAgICAgICAgICB0aGlzLl9jdXJyZW50V2lkdGggPSBuZXdXaWR0aDtcbiAgICAgICAgICAgIHRoaXMuX2N1cnJlbnRIZWlnaHQgPSBuZXdIZWlnaHQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQ2FsbGVkIHdoZW4gdGhlIHVzZXIgaGFzIGxpZnRlZCB0aGVpciBwb2ludGVyLiAqL1xuICAgIHByaXZhdGUgX3BvaW50ZXJVcCA9IChldmVudDogVG91Y2hFdmVudCB8IE1vdXNlRXZlbnQpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuX2lzU2xpZGluZykge1xuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIHRoaXMuX3JlbW92ZUdsb2JhbEV2ZW50cygpO1xuICAgICAgICAgICAgdGhpcy5fY3JvcHBlci5fcHJpbWFyeUFyZWFXaWR0aCA9IHRoaXMuX2Nyb3BwZXIuY29uZmlnLndpZHRoID0gdGhpcy5fY3VycmVudFdpZHRoO1xuICAgICAgICAgICAgdGhpcy5fY3JvcHBlci5fcHJpbWFyeUFyZWFIZWlnaHQgPSB0aGlzLl9jcm9wcGVyLmNvbmZpZy5oZWlnaHQgPSB0aGlzLl9jdXJyZW50SGVpZ2h0O1xuICAgICAgICAgICAgdGhpcy5fY3JvcHBlci5jb25maWcgPSB0aGlzLl9jcm9wcGVyLmNvbmZpZztcbiAgICAgICAgICAgIHRoaXMuX2Nyb3BwZXIuX3VwZGF0ZU1pblNjYWxlKCk7XG4gICAgICAgICAgICB0aGlzLl9pc1NsaWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0UG9pbnRlckV2ZW50ID0gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBDYWxsZWQgd2hlbiB0aGUgd2luZG93IGhhcyBsb3N0IGZvY3VzLiAqL1xuICAgIHByaXZhdGUgX3dpbmRvd0JsdXIgPSAoKSA9PiB7XG4gICAgICAgIC8vIElmIHRoZSB3aW5kb3cgaXMgYmx1cnJlZCB3aGlsZSBkcmFnZ2luZyB3ZSBuZWVkIHRvIHN0b3AgZHJhZ2dpbmcgYmVjYXVzZSB0aGVcbiAgICAgICAgLy8gYnJvd3NlciB3b24ndCBkaXNwYXRjaCB0aGUgYG1vdXNldXBgIGFuZCBgdG91Y2hlbmRgIGV2ZW50cyBhbnltb3JlLlxuICAgICAgICBpZiAodGhpcy5fbGFzdFBvaW50ZXJFdmVudCkge1xuICAgICAgICAgICAgdGhpcy5fcG9pbnRlclVwKHRoaXMuX2xhc3RQb2ludGVyRXZlbnQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfYmluZEdsb2JhbEV2ZW50cyh0cmlnZ2VyRXZlbnQ6IFRvdWNoRXZlbnQgfCBNb3VzZUV2ZW50KSB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLl9kb2N1bWVudDtcbiAgICAgICAgY29uc3QgaXNUb3VjaCA9IGlzVG91Y2hFdmVudCh0cmlnZ2VyRXZlbnQpO1xuICAgICAgICBjb25zdCBtb3ZlRXZlbnROYW1lID0gaXNUb3VjaCA/IFwidG91Y2htb3ZlXCIgOiBcIm1vdXNlbW92ZVwiO1xuICAgICAgICBjb25zdCBlbmRFdmVudE5hbWUgPSBpc1RvdWNoID8gXCJ0b3VjaGVuZFwiIDogXCJtb3VzZXVwXCI7XG4gICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihtb3ZlRXZlbnROYW1lLCB0aGlzLl9wb2ludGVyTW92ZSwgYWN0aXZlRXZlbnRPcHRpb25zKTtcbiAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKGVuZEV2ZW50TmFtZSwgdGhpcy5fcG9pbnRlclVwLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuXG4gICAgICAgIGlmIChpc1RvdWNoKSB7XG4gICAgICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaGNhbmNlbFwiLCB0aGlzLl9wb2ludGVyVXAsIGFjdGl2ZUV2ZW50T3B0aW9ucyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB3aW5kb3cgPSB0aGlzLl9nZXRXaW5kb3coKTtcblxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJiB3aW5kb3cpIHtcbiAgICAgICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwiYmx1clwiLCB0aGlzLl93aW5kb3dCbHVyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBSZW1vdmVzIGFueSBnbG9iYWwgZXZlbnQgbGlzdGVuZXJzIHRoYXQgd2UgbWF5IGhhdmUgYWRkZWQuICovXG4gICAgcHJpdmF0ZSBfcmVtb3ZlR2xvYmFsRXZlbnRzKCkge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5fZG9jdW1lbnQ7XG4gICAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1vdXNlbW92ZVwiLCB0aGlzLl9wb2ludGVyTW92ZSwgYWN0aXZlRXZlbnRPcHRpb25zKTtcbiAgICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLCB0aGlzLl9wb2ludGVyVXAsIGFjdGl2ZUV2ZW50T3B0aW9ucyk7XG4gICAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRvdWNobW92ZVwiLCB0aGlzLl9wb2ludGVyTW92ZSwgYWN0aXZlRXZlbnRPcHRpb25zKTtcbiAgICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIiwgdGhpcy5fcG9pbnRlclVwLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ0b3VjaGNhbmNlbFwiLCB0aGlzLl9wb2ludGVyVXAsIGFjdGl2ZUV2ZW50T3B0aW9ucyk7XG5cbiAgICAgICAgY29uc3Qgd2luZG93ID0gdGhpcy5fZ2V0V2luZG93KCk7XG5cbiAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgJiYgd2luZG93KSB7XG4gICAgICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImJsdXJcIiwgdGhpcy5fd2luZG93Qmx1cik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogVXNlIGRlZmF1bHRWaWV3IG9mIGluamVjdGVkIGRvY3VtZW50IGlmIGF2YWlsYWJsZSBvciBmYWxsYmFjayB0byBnbG9iYWwgd2luZG93IHJlZmVyZW5jZSAqL1xuICAgIHByaXZhdGUgX2dldFdpbmRvdygpOiBXaW5kb3cge1xuICAgICAgICByZXR1cm4gdGhpcy5fZG9jdW1lbnQuZGVmYXVsdFZpZXcgfHwgd2luZG93O1xuICAgIH1cbn1cbiIsIjwhLS0gKHNlbGVjdHN0YXJ0KTogT24gU2FmYXJpIHN0YXJ0aW5nIHRvIHNsaWRlIHRlbXBvcmFyaWx5IHRyaWdnZXJzIHRleHQgc2VsZWN0aW9uIG1vZGUgd2hpY2hcbnNob3cgdGhlIHdyb25nIGN1cnNvci4gV2UgcHJldmVudCBpdCBieSBzdG9wcGluZyB0aGUgYHNlbGVjdHN0YXJ0YCBldmVudC4gLS0+XG48ZGl2IGNsYXNzPVwiaW1hZ2UtY29udGFpbmVyXCIgI19pbWdDb250YWluZXJcbiAgICAgKHNlbGVjdHN0YXJ0KT1cIiRldmVudC5wcmV2ZW50RGVmYXVsdCgpXCJcbj5cbiAgICA8Y2FudmFzICNfaW1nQ2FudmFzPjwvY2FudmFzPlxuPC9kaXY+XG48bmljZS1jcm9wcGVyLWFyZWFcbiAgICAjX2FyZWFcbiAgICAqbmdJZj1cIl9pc0xvYWRlZEltZ1wiXG4gICAgW3JvdW5kXT1cIiEhY29uZmlnLnJvdW5kXCJcbiAgICBbcmVzaXphYmxlQXJlYV09XCIhIWNvbmZpZy5yZXNpemFibGVBcmVhXCJcbiAgICBba2VlcEFzcGVjdFJhdGlvXT1cIiEhY29uZmlnLmtlZXBBc3BlY3RSYXRpb1wiXG4gICAgW25nU3R5bGVdPVwie1xuICAgICAgICB3aWR0aDogY29uZmlnLndpZHRoICsgJ3B4JyxcbiAgICAgICAgaGVpZ2h0OiBjb25maWcuaGVpZ2h0ICsgJ3B4J1xuICAgIH1cIlxuPjwvbmljZS1jcm9wcGVyLWFyZWE+XG48YnV0dG9uIGNsYXNzPVwiY2xvc2UtYnV0dG9uXCIgbWF0LWljb24tYnV0dG9uICpuZ0lmPVwiX2lzTG9hZGVkSW1nXCIgKGNsaWNrKT1cImNsZWFuKClcIj5cbiAgICA8bWF0LWljb24+YXJyb3dfYmFjazwvbWF0LWljb24+XG48L2J1dHRvbj5cbiIsIjxkaXYgY2xhc3M9XCJyZXNpemVyXCIgI3Jlc2l6ZXIgKm5nSWY9XCJyZXNpemFibGVBcmVhXCI+PC9kaXY+XG4iXX0=
|