@recursyve/nice-ui-kit.v2 15.0.0-beta.131 → 16.0.0-beta.132
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/{esm2020 → esm2022}/lib/components/navigation/horizontal/components/basic/basic.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/navigation/horizontal/components/branch/branch.component.mjs +4 -4
- 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/{esm2020 → esm2022}/lib/components/navigation/horizontal/horizontal.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/navigation/navigation.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/navigation/navigation.module.mjs +37 -37
- 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/{esm2020 → esm2022}/lib/components/navigation/providers/hint.service.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/navigation/vertical/components/aside/aside.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/navigation/vertical/components/basic/basic.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/navigation/vertical/components/collapsable/collapsable.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/navigation/vertical/components/divider/divider.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/navigation/vertical/components/group/group.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/navigation/vertical/components/spacer/spacer.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/components/navigation/vertical/vertical.component.mjs +4 -4
- 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 +888 -889
- 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 +1 -1
- 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 +1 -1
- 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 +13 -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/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
|
@@ -0,0 +1,1269 @@
|
|
|
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
|
+
static { this.и = "NiceImageCropper"; }
|
|
57
|
+
set config(val) {
|
|
58
|
+
this._config = mergeDeep({}, new ImgCropperConfig(), val);
|
|
59
|
+
this._configPrimary = mergeDeep({}, this._config);
|
|
60
|
+
this._primaryAreaWidth = this.config.width;
|
|
61
|
+
this._primaryAreaHeight = this.config.height;
|
|
62
|
+
if (this._config.round
|
|
63
|
+
&& this.config.width !== this.config.height) {
|
|
64
|
+
throw new Error(`${NiceImageCropperComponent.и}: Both width and height must be equal when using \`ImgCropperConfig.round = true\``);
|
|
65
|
+
}
|
|
66
|
+
const maxFileSize = this._config.maxFileSize;
|
|
67
|
+
if (maxFileSize) {
|
|
68
|
+
this.maxFileSize = maxFileSize;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
get config() {
|
|
72
|
+
return this._config;
|
|
73
|
+
}
|
|
74
|
+
/** Set scale */
|
|
75
|
+
set scale(val) {
|
|
76
|
+
this.setScale(val);
|
|
77
|
+
}
|
|
78
|
+
get scale() {
|
|
79
|
+
return this._scale;
|
|
80
|
+
}
|
|
81
|
+
/** Get min scale */
|
|
82
|
+
get minScale() {
|
|
83
|
+
return this._minScale;
|
|
84
|
+
}
|
|
85
|
+
constructor(_renderer, _elementRef, cd, _ngZone, _document, viewPortRuler) {
|
|
86
|
+
this._renderer = _renderer;
|
|
87
|
+
this._elementRef = _elementRef;
|
|
88
|
+
this.cd = cd;
|
|
89
|
+
this._ngZone = _ngZone;
|
|
90
|
+
this._imgRect = {};
|
|
91
|
+
this._rotation = 0;
|
|
92
|
+
this.scaleChange = new EventEmitter();
|
|
93
|
+
/** Emits minimum supported image scale */
|
|
94
|
+
// tslint:disable-next-line:no-output-rename
|
|
95
|
+
this.minScaleChange = new EventEmitter();
|
|
96
|
+
/** Emits maximum supported image scale */
|
|
97
|
+
// tslint:disable-next-line:no-output-rename
|
|
98
|
+
this.maxScaleChange = new EventEmitter();
|
|
99
|
+
/** Emits when the image is loaded */
|
|
100
|
+
this.imageLoaded = new EventEmitter();
|
|
101
|
+
/** Emits when the cropper is ready to be interacted */
|
|
102
|
+
this.ready = new EventEmitter();
|
|
103
|
+
/** On crop new image */
|
|
104
|
+
this.cropped = new EventEmitter();
|
|
105
|
+
/** Emits when the cropper is cleaned */
|
|
106
|
+
this.cleaned = new EventEmitter();
|
|
107
|
+
/** Emit an error when the loaded image is not valid */
|
|
108
|
+
// tslint:disable-next-line: no-output-native
|
|
109
|
+
this.error = new EventEmitter();
|
|
110
|
+
/** Emits whenever the component is destroyed. */
|
|
111
|
+
this._destroy = new Subject();
|
|
112
|
+
this._pointerDown = (event) => {
|
|
113
|
+
// Don't do anything if the
|
|
114
|
+
// user is using anything other than the main mouse button.
|
|
115
|
+
if (this._isSliding || (!isTouchEvent(event) && event.button !== 0)) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
this._ngZone.run(() => {
|
|
119
|
+
this._isSliding = true;
|
|
120
|
+
this.offset = {
|
|
121
|
+
x: this._imgRect.x,
|
|
122
|
+
y: this._imgRect.y,
|
|
123
|
+
left: this._imgRect.xc,
|
|
124
|
+
top: this._imgRect.yc
|
|
125
|
+
};
|
|
126
|
+
this._lastPointerEvent = event;
|
|
127
|
+
this._startPointerEvent = getGesturePointFromEvent(event);
|
|
128
|
+
event.preventDefault();
|
|
129
|
+
this._bindGlobalEvents(event);
|
|
130
|
+
});
|
|
131
|
+
};
|
|
132
|
+
/**
|
|
133
|
+
* Called when the user has moved their pointer after
|
|
134
|
+
* starting to drag.
|
|
135
|
+
*/
|
|
136
|
+
this._pointerMove = (event) => {
|
|
137
|
+
if (this._isSliding) {
|
|
138
|
+
event.preventDefault();
|
|
139
|
+
this._lastPointerEvent = event;
|
|
140
|
+
let x;
|
|
141
|
+
let y;
|
|
142
|
+
const canvas = this._imgCanvas.nativeElement;
|
|
143
|
+
const scaleFix = this._scal3Fix;
|
|
144
|
+
const config = this.config;
|
|
145
|
+
const startP = this.offset;
|
|
146
|
+
const point = getGesturePointFromEvent(event);
|
|
147
|
+
const deltaX = point.x - this._startPointerEvent.x;
|
|
148
|
+
const deltaY = point.y - this._startPointerEvent.y;
|
|
149
|
+
if (!scaleFix || !startP) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const isMinScaleY = canvas.height * scaleFix < config.height && config.extraZoomOut;
|
|
153
|
+
const isMinScaleX = canvas.width * scaleFix < config.width && config.extraZoomOut;
|
|
154
|
+
const limitLeft = (config.width / 2 / scaleFix) >= startP.left - (deltaX / scaleFix);
|
|
155
|
+
const limitRight = (config.width / 2 / scaleFix) +
|
|
156
|
+
(canvas.width) - (startP.left - (deltaX / scaleFix)) <= config.width / scaleFix;
|
|
157
|
+
const limitTop = ((config.height / 2 / scaleFix) >= (startP.top - (deltaY / scaleFix)));
|
|
158
|
+
const limitBottom = (((config.height / 2 / scaleFix) + (canvas.height) - (startP.top - (deltaY / scaleFix))) <= (config.height / scaleFix));
|
|
159
|
+
// Limit for left
|
|
160
|
+
if ((limitLeft && !isMinScaleX) || (!limitLeft && isMinScaleX)) {
|
|
161
|
+
x = startP.x + (startP.left) - (config.width / 2 / scaleFix);
|
|
162
|
+
}
|
|
163
|
+
// Limit for right
|
|
164
|
+
if ((limitRight && !isMinScaleX) || (!limitRight && isMinScaleX)) {
|
|
165
|
+
x = startP.x + (startP.left) + (config.width / 2 / scaleFix) - canvas.width;
|
|
166
|
+
}
|
|
167
|
+
// Limit for top
|
|
168
|
+
if ((limitTop && !isMinScaleY) || (!limitTop && isMinScaleY)) {
|
|
169
|
+
y = startP.y + (startP.top) - (config.height / 2 / scaleFix);
|
|
170
|
+
}
|
|
171
|
+
// Limit for bottom
|
|
172
|
+
if ((limitBottom && !isMinScaleY) || (!limitBottom && isMinScaleY)) {
|
|
173
|
+
y = startP.y + (startP.top) + (config.height / 2 / scaleFix) - canvas.height;
|
|
174
|
+
}
|
|
175
|
+
// When press shiftKey, deprecated
|
|
176
|
+
// if (event.srcEvent && event.srcEvent.shiftKey) {
|
|
177
|
+
// if (Math.abs(event.deltaX) === Math.max(Math.abs(event.deltaX), Math.abs(event.deltaY))) {
|
|
178
|
+
// y = this.offset.top;
|
|
179
|
+
// } else {
|
|
180
|
+
// x = this.offset.left;
|
|
181
|
+
// }
|
|
182
|
+
// }
|
|
183
|
+
if (x === void 0) {
|
|
184
|
+
x = (deltaX / scaleFix) + (startP.x);
|
|
185
|
+
}
|
|
186
|
+
if (y === void 0) {
|
|
187
|
+
y = (deltaY / scaleFix) + (startP.y);
|
|
188
|
+
}
|
|
189
|
+
this._setStylesForContImg({
|
|
190
|
+
x, y
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
/** Called when the user has lifted their pointer. */
|
|
195
|
+
this._pointerUp = (event) => {
|
|
196
|
+
if (this._isSliding) {
|
|
197
|
+
event.preventDefault();
|
|
198
|
+
this._removeGlobalEvents();
|
|
199
|
+
this._isSliding = false;
|
|
200
|
+
this._startPointerEvent = null;
|
|
201
|
+
this._cropIfAutoCrop();
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
/** Called when the window has lost focus. */
|
|
205
|
+
this._windowBlur = () => {
|
|
206
|
+
// If the window is blurred while dragging we need to stop dragging because the
|
|
207
|
+
// browser won't dispatch the `mouseup` and `touchend` events anymore.
|
|
208
|
+
if (this._lastPointerEvent) {
|
|
209
|
+
this._pointerUp(this._lastPointerEvent);
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
this._document = _document;
|
|
213
|
+
viewPortRuler.change()
|
|
214
|
+
.pipe(takeUntil(this._destroy))
|
|
215
|
+
.subscribe(() => this._ngZone.run(() => this.updateCropperPosition()));
|
|
216
|
+
}
|
|
217
|
+
ngOnInit() {
|
|
218
|
+
this._ngZone.runOutsideAngular(() => {
|
|
219
|
+
const element = this._imgContainer.nativeElement;
|
|
220
|
+
element.addEventListener("mousedown", this._pointerDown, activeEventOptions);
|
|
221
|
+
element.addEventListener("touchstart", this._pointerDown, activeEventOptions);
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
ngOnDestroy() {
|
|
225
|
+
this._destroy.next();
|
|
226
|
+
this._destroy.complete();
|
|
227
|
+
const element = this._imgContainer.nativeElement;
|
|
228
|
+
this._lastPointerEvent = null;
|
|
229
|
+
this._removeGlobalEvents();
|
|
230
|
+
element.removeEventListener("mousedown", this._pointerDown, activeEventOptions);
|
|
231
|
+
element.removeEventListener("touchstart", this._pointerDown, activeEventOptions);
|
|
232
|
+
}
|
|
233
|
+
/** Load image with canvas */
|
|
234
|
+
_imgLoaded(imgElement) {
|
|
235
|
+
if (imgElement) {
|
|
236
|
+
this._img = imgElement;
|
|
237
|
+
const canvas = this._imgCanvas.nativeElement;
|
|
238
|
+
canvas.width = imgElement.width;
|
|
239
|
+
canvas.height = imgElement.height;
|
|
240
|
+
const ctx = canvas.getContext("2d");
|
|
241
|
+
ctx.clearRect(0, 0, imgElement.width, imgElement.height);
|
|
242
|
+
ctx.drawImage(imgElement, 0, 0);
|
|
243
|
+
/** set min scale */
|
|
244
|
+
this._updateMinScale(canvas);
|
|
245
|
+
this._updateMaxScale();
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
_setStylesForContImg(values) {
|
|
249
|
+
const newStyles = {};
|
|
250
|
+
if (values.x != null && values.y != null) {
|
|
251
|
+
const rootRect = this._rootRect();
|
|
252
|
+
const x = rootRect.width / 2 - (values.x);
|
|
253
|
+
const y = rootRect.height / 2 - (values.y);
|
|
254
|
+
this._imgRect.x = (values.x);
|
|
255
|
+
this._imgRect.y = (values.y);
|
|
256
|
+
this._imgRect.xc = (x);
|
|
257
|
+
this._imgRect.yc = (y);
|
|
258
|
+
}
|
|
259
|
+
newStyles.transform = `translate3d(${(this._imgRect.x)}px,${(this._imgRect.y)}px, 0)`;
|
|
260
|
+
newStyles.transform += `scale(${this._scal3Fix})`;
|
|
261
|
+
newStyles.transformOrigin = `${this._imgRect.xc}px ${this._imgRect.yc}px 0`;
|
|
262
|
+
newStyles["-webkit-transform"] = newStyles.transform;
|
|
263
|
+
newStyles["-webkit-transform-origin"] = newStyles.transformOrigin;
|
|
264
|
+
for (const key in newStyles) {
|
|
265
|
+
if (newStyles.hasOwnProperty(key)) {
|
|
266
|
+
this._renderer.setStyle(this._imgContainer.nativeElement, key, newStyles[key]);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Update area and image position only if needed,
|
|
272
|
+
* this is used when window resize
|
|
273
|
+
*/
|
|
274
|
+
updateCropperPosition() {
|
|
275
|
+
if (this.isLoaded) {
|
|
276
|
+
this.updatePosition();
|
|
277
|
+
this._updateAreaIfNeeded();
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
/** Load Image from input event */
|
|
281
|
+
selectInputEvent(img) {
|
|
282
|
+
this._currentInputElement = img.target;
|
|
283
|
+
const _img = img.target;
|
|
284
|
+
if (_img.files && _img.files.length !== 1) {
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
const fileSize = _img.files[0].size;
|
|
288
|
+
const fileName = _img.value.replace(/.*(\/|\\)/, "");
|
|
289
|
+
if (this.maxFileSize && fileSize > this.maxFileSize) {
|
|
290
|
+
const cropEvent = {
|
|
291
|
+
name: fileName,
|
|
292
|
+
type: _img.files[0].type,
|
|
293
|
+
size: fileSize,
|
|
294
|
+
error: ImgCropperError.Size
|
|
295
|
+
};
|
|
296
|
+
this.clean();
|
|
297
|
+
this.error.emit(cropEvent);
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
new Observable(observer => {
|
|
301
|
+
const reader = new FileReader();
|
|
302
|
+
reader.onerror = err => observer.error(err);
|
|
303
|
+
reader.onabort = err => observer.error(err);
|
|
304
|
+
reader.onload = (ev) => setTimeout(() => {
|
|
305
|
+
observer.next(ev);
|
|
306
|
+
observer.complete();
|
|
307
|
+
});
|
|
308
|
+
reader.readAsDataURL(_img.files[0]);
|
|
309
|
+
})
|
|
310
|
+
.pipe(take(1), takeUntil(this._destroy))
|
|
311
|
+
.subscribe((loadEvent) => {
|
|
312
|
+
const originalDataURL = loadEvent.target.result;
|
|
313
|
+
this.loadImage({
|
|
314
|
+
name: fileName,
|
|
315
|
+
size: _img.files[0].size,
|
|
316
|
+
type: this.config.type || _img.files[0].type,
|
|
317
|
+
originalDataURL
|
|
318
|
+
});
|
|
319
|
+
this.cd.markForCheck();
|
|
320
|
+
}, () => {
|
|
321
|
+
const cropEvent = {
|
|
322
|
+
name: fileName,
|
|
323
|
+
size: fileSize,
|
|
324
|
+
error: ImgCropperError.Other,
|
|
325
|
+
errorMsg: "The File could not be loaded.",
|
|
326
|
+
type: _img.files[0].type
|
|
327
|
+
};
|
|
328
|
+
this.clean();
|
|
329
|
+
this.error.emit(cropEvent);
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
/** Set the size of the image, the values can be 0 between 1, where 1 is the original size */
|
|
333
|
+
setScale(size, noAutoCrop) {
|
|
334
|
+
// fix min scale
|
|
335
|
+
const newSize = size >= this.minScale && size <= 1 ? size : this.minScale;
|
|
336
|
+
// check
|
|
337
|
+
const changed = size != null && size !== this.scale && newSize !== this.scale;
|
|
338
|
+
this._scale = size;
|
|
339
|
+
if (!changed) {
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
this._scal3Fix = newSize;
|
|
343
|
+
this._updateAbsoluteScale();
|
|
344
|
+
if (this.isLoaded) {
|
|
345
|
+
if (changed) {
|
|
346
|
+
const originPosition = { ...this._imgRect };
|
|
347
|
+
this.offset = {
|
|
348
|
+
x: originPosition.x,
|
|
349
|
+
y: originPosition.y,
|
|
350
|
+
left: originPosition.xc,
|
|
351
|
+
top: originPosition.yc
|
|
352
|
+
};
|
|
353
|
+
this._setStylesForContImg({});
|
|
354
|
+
this._simulatePointerMove();
|
|
355
|
+
}
|
|
356
|
+
else {
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
else if (this.minScale) {
|
|
361
|
+
this._setStylesForContImg({
|
|
362
|
+
...this._getCenterPoints()
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
else {
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
this.scaleChange.emit(size);
|
|
369
|
+
if (!noAutoCrop) {
|
|
370
|
+
this._cropIfAutoCrop();
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
_getCenterPoints() {
|
|
374
|
+
const root = this._elementRef.nativeElement;
|
|
375
|
+
const img = this._imgCanvas.nativeElement;
|
|
376
|
+
const x = (root.offsetWidth - (img.width)) / 2;
|
|
377
|
+
const y = (root.offsetHeight - (img.height)) / 2;
|
|
378
|
+
return {
|
|
379
|
+
x,
|
|
380
|
+
y
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Fit to screen
|
|
385
|
+
*/
|
|
386
|
+
fitToScreen() {
|
|
387
|
+
const container = this._elementRef.nativeElement;
|
|
388
|
+
const min = {
|
|
389
|
+
width: container.offsetWidth,
|
|
390
|
+
height: container.offsetHeight
|
|
391
|
+
};
|
|
392
|
+
const { width, height } = this._img;
|
|
393
|
+
const minScale = {
|
|
394
|
+
width: min.width / width,
|
|
395
|
+
height: min.height / height
|
|
396
|
+
};
|
|
397
|
+
const result = Math.max(minScale.width, minScale.height);
|
|
398
|
+
this.setScale(result);
|
|
399
|
+
}
|
|
400
|
+
fit() {
|
|
401
|
+
this.setScale(this.minScale);
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Simulate pointerMove with clientX = 0 and clientY = 0,
|
|
405
|
+
* this is used by `setScale` and `rotate`
|
|
406
|
+
*/
|
|
407
|
+
_simulatePointerMove() {
|
|
408
|
+
this._isSliding = true;
|
|
409
|
+
this._startPointerEvent = {
|
|
410
|
+
x: 0,
|
|
411
|
+
y: 0
|
|
412
|
+
};
|
|
413
|
+
this._pointerMove({
|
|
414
|
+
clientX: 0,
|
|
415
|
+
clientY: 0,
|
|
416
|
+
type: "n",
|
|
417
|
+
preventDefault: () => { }
|
|
418
|
+
});
|
|
419
|
+
this._isSliding = false;
|
|
420
|
+
this._startPointerEvent = null;
|
|
421
|
+
}
|
|
422
|
+
_markForCheck() {
|
|
423
|
+
this.cd.markForCheck();
|
|
424
|
+
}
|
|
425
|
+
updatePosition(xOrigin, yOrigin) {
|
|
426
|
+
const hostRect = this._rootRect();
|
|
427
|
+
const areaRect = this._areaCropperRect();
|
|
428
|
+
const areaWidth = areaRect.width > hostRect.width
|
|
429
|
+
? hostRect.width
|
|
430
|
+
: areaRect.width;
|
|
431
|
+
const areaHeight = areaRect.height > hostRect.height
|
|
432
|
+
? hostRect.height
|
|
433
|
+
: areaRect.height;
|
|
434
|
+
let x;
|
|
435
|
+
let y;
|
|
436
|
+
if (xOrigin == null && yOrigin == null) {
|
|
437
|
+
xOrigin = this._imgRect.xc;
|
|
438
|
+
yOrigin = this._imgRect.yc;
|
|
439
|
+
}
|
|
440
|
+
x = (areaRect.left - hostRect.left);
|
|
441
|
+
y = (areaRect.top - hostRect.top);
|
|
442
|
+
x -= (xOrigin - (areaWidth / 2));
|
|
443
|
+
y -= (yOrigin - (areaHeight / 2));
|
|
444
|
+
this._setStylesForContImg({
|
|
445
|
+
x, y
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
_slideEnd() {
|
|
449
|
+
this._cropIfAutoCrop();
|
|
450
|
+
}
|
|
451
|
+
_cropIfAutoCrop() {
|
|
452
|
+
if (this.config.autoCrop) {
|
|
453
|
+
this.crop();
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
/** + */
|
|
457
|
+
zoomIn() {
|
|
458
|
+
const scale = this._scal3Fix + .05;
|
|
459
|
+
if (scale > this.minScale && scale <= this._maxScale) {
|
|
460
|
+
this.setScale(scale);
|
|
461
|
+
}
|
|
462
|
+
else {
|
|
463
|
+
this.setScale(this._maxScale);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
/** Clean the img cropper */
|
|
467
|
+
clean() {
|
|
468
|
+
// fix choosing the same image does not load
|
|
469
|
+
if (this._currentInputElement) {
|
|
470
|
+
this._currentInputElement.value = "";
|
|
471
|
+
this._currentInputElement = null;
|
|
472
|
+
}
|
|
473
|
+
if (this.isLoaded) {
|
|
474
|
+
this._imgRect = {};
|
|
475
|
+
this.offset = undefined;
|
|
476
|
+
this.scale = undefined;
|
|
477
|
+
this._scal3Fix = undefined;
|
|
478
|
+
this._rotation = 0;
|
|
479
|
+
this._minScale = undefined;
|
|
480
|
+
this._isLoadedImg = false;
|
|
481
|
+
this.isLoaded = false;
|
|
482
|
+
this.isCropped = false;
|
|
483
|
+
this._currentLoadConfig = undefined;
|
|
484
|
+
this.config = this._configPrimary;
|
|
485
|
+
const canvas = this._imgCanvas.nativeElement;
|
|
486
|
+
canvas.width = 0;
|
|
487
|
+
canvas.height = 0;
|
|
488
|
+
this.cleaned.emit(null);
|
|
489
|
+
this.cd.markForCheck();
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
/** - */
|
|
493
|
+
zoomOut() {
|
|
494
|
+
const scale = this._scal3Fix - .05;
|
|
495
|
+
if (scale > this.minScale && scale <= this._maxScale) {
|
|
496
|
+
this.setScale(scale);
|
|
497
|
+
}
|
|
498
|
+
else {
|
|
499
|
+
this.fit();
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
center() {
|
|
503
|
+
const newStyles = {
|
|
504
|
+
...this._getCenterPoints()
|
|
505
|
+
};
|
|
506
|
+
this._setStylesForContImg(newStyles);
|
|
507
|
+
this._cropIfAutoCrop();
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* load an image from a given configuration,
|
|
511
|
+
* or from the result of a cropped image
|
|
512
|
+
*/
|
|
513
|
+
loadImage(config, fn) {
|
|
514
|
+
this.clean();
|
|
515
|
+
const _config = this._currentLoadConfig = typeof config === "string"
|
|
516
|
+
? { originalDataURL: config }
|
|
517
|
+
: { ...config };
|
|
518
|
+
let src = _config.originalDataURL;
|
|
519
|
+
this._primaryAreaWidth = this._configPrimary.width;
|
|
520
|
+
this._primaryAreaHeight = this._configPrimary.height;
|
|
521
|
+
if (_config.areaWidth && _config.areaHeight) {
|
|
522
|
+
this.config.width = _config.areaWidth;
|
|
523
|
+
this.config.height = _config.areaHeight;
|
|
524
|
+
}
|
|
525
|
+
src = normalizeSVG(src);
|
|
526
|
+
const img = createHtmlImg(src);
|
|
527
|
+
const cropEvent = { ..._config };
|
|
528
|
+
new Observable(observer => {
|
|
529
|
+
img.onerror = err => observer.error(err);
|
|
530
|
+
img.onabort = err => observer.error(err);
|
|
531
|
+
img.onload = () => observer.next(null);
|
|
532
|
+
})
|
|
533
|
+
.pipe(take(1), takeUntil(this._destroy))
|
|
534
|
+
.subscribe(() => {
|
|
535
|
+
this._imgLoaded(img);
|
|
536
|
+
this._isLoadedImg = true;
|
|
537
|
+
this.imageLoaded.emit(cropEvent);
|
|
538
|
+
this.cd.markForCheck();
|
|
539
|
+
this._ngZone.runOutsideAngular(() => {
|
|
540
|
+
this._ngZone
|
|
541
|
+
.onStable
|
|
542
|
+
.asObservable()
|
|
543
|
+
.pipe(take(1), takeUntil(this._destroy))
|
|
544
|
+
.subscribe(() => setTimeout(() => this._ngZone.run(() => this._positionImg(cropEvent, fn))));
|
|
545
|
+
});
|
|
546
|
+
}, () => {
|
|
547
|
+
const error = {
|
|
548
|
+
name: _config.name,
|
|
549
|
+
error: ImgCropperError.Type,
|
|
550
|
+
type: _config.type,
|
|
551
|
+
size: _config.size
|
|
552
|
+
};
|
|
553
|
+
this.error.emit(error);
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
_updateAreaIfNeeded() {
|
|
557
|
+
if (!this._config.responsiveArea) {
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
const rootRect = this._rootRect();
|
|
561
|
+
const areaRect = this._areaCropperRect();
|
|
562
|
+
const minWidth = this.config.minWidth || 1;
|
|
563
|
+
const minHeight = this.config.minHeight || 1;
|
|
564
|
+
if (!(areaRect.width > rootRect.width
|
|
565
|
+
|| areaRect.height > rootRect.height
|
|
566
|
+
|| areaRect.width < this._primaryAreaWidth
|
|
567
|
+
|| areaRect.height < this._primaryAreaHeight)) {
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
const areaWidthConf = Math.max(this.config.width, minWidth);
|
|
571
|
+
const areaWidthMax = Math.max(rootRect.width, minWidth);
|
|
572
|
+
const minHost = Math.min(Math.max(rootRect.width, minWidth), Math.max(rootRect.height, minHeight));
|
|
573
|
+
const currentScale = this._scal3Fix;
|
|
574
|
+
let newScale = 0;
|
|
575
|
+
const roundConf = this.config.round;
|
|
576
|
+
if (roundConf) {
|
|
577
|
+
this.config.width = this.config.height = minHost;
|
|
578
|
+
}
|
|
579
|
+
else {
|
|
580
|
+
if (areaWidthConf === areaRect.width) {
|
|
581
|
+
if (areaWidthMax > this._primaryAreaWidth) {
|
|
582
|
+
this.config.width = this._primaryAreaWidth;
|
|
583
|
+
this.config.height = (this._primaryAreaWidth * areaRect.height) / areaRect.width;
|
|
584
|
+
newScale = (currentScale * this._primaryAreaWidth) / areaRect.width;
|
|
585
|
+
}
|
|
586
|
+
else {
|
|
587
|
+
this.config.width = areaWidthMax;
|
|
588
|
+
this.config.height = (areaWidthMax * areaRect.height) / areaRect.width;
|
|
589
|
+
newScale = (currentScale * areaWidthMax) / areaRect.width;
|
|
590
|
+
}
|
|
591
|
+
this._updateMinScale();
|
|
592
|
+
this._updateMaxScale();
|
|
593
|
+
this.setScale(newScale, true);
|
|
594
|
+
this._markForCheck();
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
_updateAbsoluteScale() {
|
|
599
|
+
const scale = this._scal3Fix / (this.config.width / this._primaryAreaWidth);
|
|
600
|
+
this._absoluteScale = scale;
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* Load Image from URL
|
|
604
|
+
* @deprecated Use `loadImage` instead of `setImageUrl`
|
|
605
|
+
* @param src URL
|
|
606
|
+
* @param fn function that will be called before emit the event loaded
|
|
607
|
+
*/
|
|
608
|
+
setImageUrl(src, fn) {
|
|
609
|
+
this.loadImage(src, fn);
|
|
610
|
+
}
|
|
611
|
+
_positionImg(cropEvent, fn) {
|
|
612
|
+
const loadConfig = this._currentLoadConfig;
|
|
613
|
+
this._updateMinScale(this._imgCanvas.nativeElement);
|
|
614
|
+
this._updateMaxScale();
|
|
615
|
+
this.isLoaded = false;
|
|
616
|
+
if (fn) {
|
|
617
|
+
fn();
|
|
618
|
+
}
|
|
619
|
+
else {
|
|
620
|
+
if (loadConfig.scale) {
|
|
621
|
+
this.setScale(loadConfig.scale, true);
|
|
622
|
+
}
|
|
623
|
+
else {
|
|
624
|
+
this.setScale(this.minScale, true);
|
|
625
|
+
}
|
|
626
|
+
this.rotate(loadConfig.rotation || 0);
|
|
627
|
+
this._updateAreaIfNeeded();
|
|
628
|
+
this._markForCheck();
|
|
629
|
+
this._ngZone.runOutsideAngular(() => {
|
|
630
|
+
this._ngZone
|
|
631
|
+
.onStable
|
|
632
|
+
.asObservable()
|
|
633
|
+
.pipe(take(1), takeUntil(this._destroy))
|
|
634
|
+
.subscribe(() => {
|
|
635
|
+
if (loadConfig.xOrigin != null && loadConfig.yOrigin != null) {
|
|
636
|
+
this.updatePosition(loadConfig.xOrigin, loadConfig.yOrigin);
|
|
637
|
+
}
|
|
638
|
+
this._updateAreaIfNeeded();
|
|
639
|
+
this.isLoaded = true;
|
|
640
|
+
this._cropIfAutoCrop();
|
|
641
|
+
this._ngZone.run(() => {
|
|
642
|
+
this._markForCheck();
|
|
643
|
+
this.ready.emit(cropEvent);
|
|
644
|
+
});
|
|
645
|
+
});
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
rotate(degrees) {
|
|
650
|
+
let validDegrees = _normalizeDegrees(degrees);
|
|
651
|
+
// If negative convert to positive
|
|
652
|
+
if (validDegrees < 0) {
|
|
653
|
+
validDegrees += 360;
|
|
654
|
+
}
|
|
655
|
+
const newRotation = _normalizeDegrees((this._rotation || 0) + validDegrees);
|
|
656
|
+
if (newRotation === this._rotation) {
|
|
657
|
+
return;
|
|
658
|
+
}
|
|
659
|
+
const degreesRad = validDegrees * Math.PI / 180;
|
|
660
|
+
const canvas = this._imgCanvas.nativeElement;
|
|
661
|
+
const canvasClon = createCanvasImg(canvas);
|
|
662
|
+
const ctx = canvas.getContext("2d");
|
|
663
|
+
this._rotation = newRotation;
|
|
664
|
+
// clear
|
|
665
|
+
ctx.clearRect(0, 0, canvasClon.width, canvasClon.height);
|
|
666
|
+
// rotate canvas image
|
|
667
|
+
const transform = `rotate(${validDegrees}deg) scale(${1 / this._scal3Fix})`;
|
|
668
|
+
const transformOrigin = `${this._imgRect.xc}px ${this._imgRect.yc}px 0`;
|
|
669
|
+
canvas.style.transform = transform;
|
|
670
|
+
// tslint:disable-next-line: deprecation
|
|
671
|
+
canvas.style.webkitTransform = transform;
|
|
672
|
+
canvas.style.transformOrigin = transformOrigin;
|
|
673
|
+
// tslint:disable-next-line: deprecation
|
|
674
|
+
canvas.style.webkitTransformOrigin = transformOrigin;
|
|
675
|
+
const { left, top } = canvas.getBoundingClientRect();
|
|
676
|
+
// save rect
|
|
677
|
+
const canvasRect = canvas.getBoundingClientRect();
|
|
678
|
+
// remove rotate styles
|
|
679
|
+
canvas.removeAttribute("style");
|
|
680
|
+
// set w & h
|
|
681
|
+
const w = canvasRect.width;
|
|
682
|
+
const h = canvasRect.height;
|
|
683
|
+
ctx.canvas.width = w;
|
|
684
|
+
ctx.canvas.height = h;
|
|
685
|
+
// clear
|
|
686
|
+
ctx.clearRect(0, 0, w, h);
|
|
687
|
+
// translate and rotate
|
|
688
|
+
ctx.translate(w / 2, h / 2);
|
|
689
|
+
ctx.rotate(degreesRad);
|
|
690
|
+
ctx.drawImage(canvasClon, -canvasClon.width / 2, -canvasClon.height / 2);
|
|
691
|
+
// Update min scale
|
|
692
|
+
this._updateMinScale(canvas);
|
|
693
|
+
this._updateMaxScale();
|
|
694
|
+
// set the minimum scale, only if necessary
|
|
695
|
+
if (this.scale < this.minScale) {
|
|
696
|
+
this.setScale(0, true);
|
|
697
|
+
} // ↑ no AutoCrop
|
|
698
|
+
const rootRect = this._rootRect();
|
|
699
|
+
this._setStylesForContImg({
|
|
700
|
+
x: (left - rootRect.left),
|
|
701
|
+
y: (top - rootRect.top)
|
|
702
|
+
});
|
|
703
|
+
// keep image inside the frame
|
|
704
|
+
const originPosition = { ...this._imgRect };
|
|
705
|
+
this.offset = {
|
|
706
|
+
x: originPosition.x,
|
|
707
|
+
y: originPosition.y,
|
|
708
|
+
left: originPosition.xc,
|
|
709
|
+
top: originPosition.yc
|
|
710
|
+
};
|
|
711
|
+
this._setStylesForContImg({});
|
|
712
|
+
this._simulatePointerMove();
|
|
713
|
+
this._cropIfAutoCrop();
|
|
714
|
+
}
|
|
715
|
+
_updateMinScale(canvas) {
|
|
716
|
+
if (!canvas) {
|
|
717
|
+
canvas = this._imgCanvas.nativeElement;
|
|
718
|
+
}
|
|
719
|
+
const config = this.config;
|
|
720
|
+
const minScale = (config.extraZoomOut ? Math.min : Math.max)(config.width / canvas.width, config.height / canvas.height);
|
|
721
|
+
this._minScale = minScale;
|
|
722
|
+
this.minScaleChange.emit(minScale);
|
|
723
|
+
}
|
|
724
|
+
_updateMaxScale() {
|
|
725
|
+
const maxScale = (this.config.width / this._primaryAreaWidth);
|
|
726
|
+
this._maxScale = maxScale;
|
|
727
|
+
this.maxScaleChange.emit(maxScale);
|
|
728
|
+
}
|
|
729
|
+
/**
|
|
730
|
+
* Resize & crop image
|
|
731
|
+
*/
|
|
732
|
+
crop(config) {
|
|
733
|
+
const newConfig = config
|
|
734
|
+
? mergeDeep({}, this.config || new ImgCropperConfig(), config) : this.config;
|
|
735
|
+
const cropEvent = this._imgCrop(newConfig);
|
|
736
|
+
this.cd.markForCheck();
|
|
737
|
+
return cropEvent;
|
|
738
|
+
}
|
|
739
|
+
/**
|
|
740
|
+
* @docs-private
|
|
741
|
+
*/
|
|
742
|
+
_imgCrop(myConfig) {
|
|
743
|
+
const canvasElement = document.createElement("canvas");
|
|
744
|
+
const areaRect = this._areaCropperRect();
|
|
745
|
+
const canvasRect = this._canvasRect();
|
|
746
|
+
const scaleFix = this._scal3Fix;
|
|
747
|
+
const left = (areaRect.left - canvasRect.left) / scaleFix;
|
|
748
|
+
const top = (areaRect.top - canvasRect.top) / scaleFix;
|
|
749
|
+
const { output } = myConfig;
|
|
750
|
+
const currentImageLoadConfig = this._currentLoadConfig;
|
|
751
|
+
const area = {
|
|
752
|
+
width: myConfig.width,
|
|
753
|
+
height: myConfig.height
|
|
754
|
+
};
|
|
755
|
+
canvasElement.width = area.width / scaleFix;
|
|
756
|
+
canvasElement.height = area.height / scaleFix;
|
|
757
|
+
const ctx = canvasElement.getContext("2d");
|
|
758
|
+
if (myConfig.fill) {
|
|
759
|
+
ctx.fillStyle = myConfig.fill;
|
|
760
|
+
ctx.fillRect(0, 0, canvasElement.width, canvasElement.height);
|
|
761
|
+
}
|
|
762
|
+
ctx.drawImage(this._imgCanvas.nativeElement, -(left), -(top));
|
|
763
|
+
const result = canvasElement;
|
|
764
|
+
if (myConfig.output === ImgResolution.Default) {
|
|
765
|
+
resizeCanvas(result, this._configPrimary.width, this._configPrimary.height);
|
|
766
|
+
}
|
|
767
|
+
else if (typeof output === "object") {
|
|
768
|
+
if (output.width && output.height) {
|
|
769
|
+
resizeCanvas(result, output.width, output.height);
|
|
770
|
+
}
|
|
771
|
+
else if (output.width) {
|
|
772
|
+
const newHeight = area.height * output.width / area.width;
|
|
773
|
+
resizeCanvas(result, output.width, newHeight);
|
|
774
|
+
}
|
|
775
|
+
else if (output.height) {
|
|
776
|
+
const newWidth = area.width * output.height / area.height;
|
|
777
|
+
resizeCanvas(result, newWidth, output.height);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
const type = currentImageLoadConfig.originalDataURL.startsWith("http")
|
|
781
|
+
? currentImageLoadConfig.type || myConfig.type
|
|
782
|
+
: myConfig.type || currentImageLoadConfig.type;
|
|
783
|
+
const dataURL = result.toDataURL(type);
|
|
784
|
+
const cropEvent = {
|
|
785
|
+
dataURL,
|
|
786
|
+
type,
|
|
787
|
+
name: currentImageLoadConfig.name,
|
|
788
|
+
areaWidth: this._primaryAreaWidth,
|
|
789
|
+
areaHeight: this._primaryAreaHeight,
|
|
790
|
+
width: result.width,
|
|
791
|
+
height: result.height,
|
|
792
|
+
originalDataURL: currentImageLoadConfig.originalDataURL,
|
|
793
|
+
scale: this._absoluteScale,
|
|
794
|
+
rotation: this._rotation,
|
|
795
|
+
left: (areaRect.left - canvasRect.left) / this._scal3Fix,
|
|
796
|
+
top: (areaRect.top - canvasRect.top) / this._scal3Fix,
|
|
797
|
+
size: currentImageLoadConfig.size,
|
|
798
|
+
xOrigin: this._imgRect.xc,
|
|
799
|
+
yOrigin: this._imgRect.yc,
|
|
800
|
+
position: {
|
|
801
|
+
x: this._imgRect.xc,
|
|
802
|
+
y: this._imgRect.yc
|
|
803
|
+
}
|
|
804
|
+
};
|
|
805
|
+
this.isCropped = true;
|
|
806
|
+
this.cropped.emit(cropEvent);
|
|
807
|
+
return cropEvent;
|
|
808
|
+
}
|
|
809
|
+
_rootRect() {
|
|
810
|
+
return this._elementRef.nativeElement.getBoundingClientRect();
|
|
811
|
+
}
|
|
812
|
+
_areaCropperRect() {
|
|
813
|
+
return this._areaRef.nativeElement.getBoundingClientRect();
|
|
814
|
+
}
|
|
815
|
+
_canvasRect() {
|
|
816
|
+
return this._imgCanvas.nativeElement.getBoundingClientRect();
|
|
817
|
+
}
|
|
818
|
+
_bindGlobalEvents(triggerEvent) {
|
|
819
|
+
const element = this._document;
|
|
820
|
+
const isTouch = isTouchEvent(triggerEvent);
|
|
821
|
+
const moveEventName = isTouch ? "touchmove" : "mousemove";
|
|
822
|
+
const endEventName = isTouch ? "touchend" : "mouseup";
|
|
823
|
+
element.addEventListener(moveEventName, this._pointerMove, activeEventOptions);
|
|
824
|
+
element.addEventListener(endEventName, this._pointerUp, activeEventOptions);
|
|
825
|
+
if (isTouch) {
|
|
826
|
+
element.addEventListener("touchcancel", this._pointerUp, activeEventOptions);
|
|
827
|
+
}
|
|
828
|
+
const window = this._getWindow();
|
|
829
|
+
if (typeof window !== "undefined" && window) {
|
|
830
|
+
window.addEventListener("blur", this._windowBlur);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
/** Removes any global event listeners that we may have added. */
|
|
834
|
+
_removeGlobalEvents() {
|
|
835
|
+
const element = this._document;
|
|
836
|
+
element.removeEventListener("mousemove", this._pointerMove, activeEventOptions);
|
|
837
|
+
element.removeEventListener("mouseup", this._pointerUp, activeEventOptions);
|
|
838
|
+
element.removeEventListener("touchmove", this._pointerMove, activeEventOptions);
|
|
839
|
+
element.removeEventListener("touchend", this._pointerUp, activeEventOptions);
|
|
840
|
+
element.removeEventListener("touchcancel", this._pointerUp, activeEventOptions);
|
|
841
|
+
const window = this._getWindow();
|
|
842
|
+
if (typeof window !== "undefined" && window) {
|
|
843
|
+
window.removeEventListener("blur", this._windowBlur);
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
/** Use defaultView of injected document if available or fallback to global window reference */
|
|
847
|
+
_getWindow() {
|
|
848
|
+
return this._document.defaultView || window;
|
|
849
|
+
}
|
|
850
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.5", 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 }); }
|
|
851
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.5", 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 }); }
|
|
852
|
+
}
|
|
853
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.5", 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
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.5", ngImport: i0, type: NiceCropperAreaComponent, deps: [{ token: DOCUMENT }, { token: i0.ElementRef }, { token: NiceImageCropperComponent }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1248
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.5", 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 }); }
|
|
1249
|
+
}
|
|
1250
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.5", 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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QyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1NBQ3hEO0lBQ0wsQ0FBQztJQUVELCtGQUErRjtJQUN2RixVQUFVO1FBQ2QsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsSUFBSSxNQUFNLENBQUM7SUFDaEQsQ0FBQzs4R0FsU1Esd0JBQXdCLGtCQTJCckIsUUFBUTtrR0EzQlgsd0JBQXdCLHFURTd6Q3JDLGtFQUNBOzsyRkY0ekNhLHdCQUF3QjtrQkFQcEMsU0FBUzsrQkFDSSxtQkFBbUIsaUJBR2QsaUJBQWlCLENBQUMsSUFBSSxtQkFDcEIsdUJBQXVCLENBQUMsTUFBTTs7MEJBNkIxQyxNQUFNOzJCQUFDLFFBQVE7K0hBekJILFFBQVE7c0JBRHhCLFNBQVM7dUJBQUMsU0FBUztnQkFJYixlQUFlO3NCQURyQixLQUFLO2dCQUtDLEtBQUs7c0JBRlgsS0FBSzs7c0JBQ0wsV0FBVzt1QkFBQyxhQUFhO2dCQThCZixhQUFhO3NCQUR2QixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBBZGFwdGVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL0EtbC15LWwtZS9BbHlsZS1VSS90cmVlLzEwLjUuMy9zcmMvbGliL2ltYWdlLWNyb3BwZXJcbiAqL1xuXG5pbXBvcnQgeyBub3JtYWxpemVQYXNzaXZlTGlzdGVuZXJPcHRpb25zIH0gZnJvbSBcIkBhbmd1bGFyL2Nkay9wbGF0Zm9ybVwiO1xuaW1wb3J0IHsgVmlld3BvcnRSdWxlciB9IGZyb20gXCJAYW5ndWxhci9jZGsvc2Nyb2xsaW5nXCI7XG5pbXBvcnQgeyBET0NVTUVOVCB9IGZyb20gXCJAYW5ndWxhci9jb21tb25cIjtcbmltcG9ydCB7XG4gICAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gICAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgQ29tcG9uZW50LFxuICAgIEVsZW1lbnRSZWYsXG4gICAgRXZlbnRFbWl0dGVyLCBIb3N0QmluZGluZyxcbiAgICBJbmplY3QsXG4gICAgSW5wdXQsXG4gICAgTmdab25lLFxuICAgIE9uRGVzdHJveSxcbiAgICBPbkluaXQsXG4gICAgT3V0cHV0LFxuICAgIFJlbmRlcmVyMixcbiAgICBWaWV3Q2hpbGQsXG4gICAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IE9ic2VydmFibGUsIFN1YmplY3QgfSBmcm9tIFwicnhqc1wiO1xuaW1wb3J0IHsgdGFrZSwgdGFrZVVudGlsIH0gZnJvbSBcInJ4anMvb3BlcmF0b3JzXCI7XG5pbXBvcnQgeyByZXNpemVDYW52YXMgfSBmcm9tIFwiLi9yZXNpemUtY2FudmFzXCI7XG5cbmNvbnN0IGFjdGl2ZUV2ZW50T3B0aW9ucyA9IG5vcm1hbGl6ZVBhc3NpdmVMaXN0ZW5lck9wdGlvbnMoeyBwYXNzaXZlOiBmYWxzZSB9KTtcblxuLyoqIEltYWdlIENyb3BwZXIgQ29uZmlnICovXG5leHBvcnQgY2xhc3MgSW1nQ3JvcHBlckNvbmZpZyB7XG4gICAgLyoqIENyb3BwZXIgYXJlYSB3aWR0aCAqL1xuICAgIHdpZHRoID0gMjUwO1xuICAgIC8qKiBDcm9wcGVyIGFyZWEgaGVpZ2h0ICovXG4gICAgaGVpZ2h0ID0gMjAwO1xuICAgIG1pbldpZHRoID0gNDA7XG4gICAgbWluSGVpZ2h0ID0gNDA7XG4gICAgLyoqIElmIHRoaXMgaXMgbm90IGRlZmluZWQsIHRoZSBuZXcgaW1hZ2Ugd2lsbCBiZSBhdXRvbWF0aWNhbGx5IGRlZmluZWQuICovXG4gICAgdHlwZT86IHN0cmluZztcbiAgICAvKiogQmFja2dyb3VuZCBjb2xvciggZGVmYXVsdDogbnVsbCksIGlmIGlzIG51bGwgaW4gcG5nIGlzIHRyYW5zcGFyZW50IGJ1dCBub3QgaW4ganBnLiAqL1xuICAgIGZpbGw/OiBzdHJpbmcgfCBudWxsO1xuICAgIC8qKlxuICAgICAqIFNldCBhbnRpLWFsaWFzZWQgKGRlZmF1bHQ6IHRydWUpXG4gICAgICogQGRlcHJlY2F0ZWQgdGhpcyBpcyBub3QgbmVjZXNzYXJ5IGFzIHRoZSBjcm9wcGVyIHdpbGwgYXV0b21hdGljYWxseSByZXNpemUgdGhlIGltYWdlXG4gICAgICogdG8gdGhlIGJlc3QgcXVhbGl0eVxuICAgICAqL1xuICAgIGFudGlBbGlhc2VkID0gdHJ1ZTtcbiAgICBhdXRvQ3JvcD86IGJvb2xlYW47XG4gICAgb3V0cHV0PzogSW1nT3V0cHV0IHwgSW1nUmVzb2x1dGlvbiA9IEltZ1Jlc29sdXRpb24uRGVmYXVsdDtcbiAgICAvKipcbiAgICAgKiBab29tIG91dCB1bnRpbCB0aGUgZW50aXJlIGltYWdlIGZpdHMgaW50byB0aGUgY3JvcHBpbmcgYXJlYS5cbiAgICAgKiBkZWZhdWx0OiBmYWxzZVxuICAgICAqL1xuICAgIGV4dHJhWm9vbU91dD86IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogRW1pdCBldmVudCBgZXJyb3JgIGlmIHRoZSBmaWxlIHNpemUgaW4gYnl0ZXMgZm9yIHRoZSBsaW1pdC5cbiAgICAgKiBOb3RlOiBJdCBvbmx5IHdvcmtzIHdoZW4gdGhlIGltYWdlIGlzIHJlY2VpdmVkIGZyb20gdGhlIGA8aW5wdXQ+YCBldmVudC5cbiAgICAgKi9cbiAgICBtYXhGaWxlU2l6ZT86IG51bWJlciB8IG51bGw7XG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgY3JvcHBlciBhcmVhIHdpbGwgYmUgcm91bmQuXG4gICAgICogVGhpcyBpbXBsaWVzIHRoYXQgdGhlIGNyb3BwZXIgYXJlYSB3aWxsIG1haW50YWluIGl0cyBhc3BlY3QgcmF0aW8uXG4gICAgICogZGVmYXVsdDogZmFsc2VcbiAgICAgKi9cbiAgICByb3VuZD86IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgY3JvcHBlciBhcmVhIGlzIHJlc2l6YWJsZS5cbiAgICAgKiBkZWZhdWx0OiBmYWxzZVxuICAgICAqL1xuICAgIHJlc2l6YWJsZUFyZWE/OiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIEtlZXAgdGhlIHdpZHRoIGFuZCBoZWlnaHQgb2YgdGhlIGdyb3dpbmcgYXJlYSB0aGUgc2FtZSBhY2NvcmRpbmdcbiAgICAgKiB0byBgSW1nQ3JvcHBlckNvbmZpZy53aWR0aGAgYW5kIGBJbWdDcm9wcGVyQ29uZmlnLmhlaWdodGBcbiAgICAgKiBkZWZhdWx0OiBmYWxzZVxuICAgICAqL1xuICAgIGtlZXBBc3BlY3RSYXRpbz86IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgY3JvcHBlciBhcmVhIGlzIHJlc3BvbnNpdmUuXG4gICAgICogQnkgZGVmYXVsdCwgdGhlIHdpZHRoIGFuZCBoZWlnaHQgb2YgdGhlIGNyb3BwZXIgYXJlYSBpcyBmaXhlZCxcbiAgICAgKiBzbyBjYW4gdXNlIHdoZW4gdGhlIGNyb3BwZXIgYXJlYSBpcyBsYXJnZXIgdGhhbiBpdHMgY29udGFpbmVyLFxuICAgICAqIG90aGVyd2lzZSB0aGlzIHdpbGwgYnJpbmcgcHJvYmxlbXMgd2hlbiBjcm9wcGluZy5cbiAgICAgKi9cbiAgICByZXNwb25zaXZlQXJlYT86IGJvb2xlYW47XG59XG5cbi8qKlxuICogVGhlIG91dHB1dCBpbWFnZVxuICogV2l0aCB0aGlzIG9wdGlvbiB5b3UgY2FuIHJlc2l6ZSB0aGUgb3V0cHV0IGltYWdlLlxuICogSWYgYHdpZHRoYCBvciBgaGVpZ2h0YCBhcmUgMCwgdGhpcyB3aWxsIGJlIHNldCBhdXRvbWF0aWNhbGx5LlxuICogQm90aCBjYW5ub3QgYmUgMC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJbWdPdXRwdXQge1xuICAgIC8qKlxuICAgICAqIFRoZSBjcm9wcGVkIGltYWdlIHdpbGwgYmUgcmVzaXplZCB0byB0aGlzIGB3aWR0aGAuXG4gICAgICovXG4gICAgd2lkdGg6IG51bWJlcjtcbiAgICAvKipcbiAgICAgKiBDcm9wcGVkIGltYWdlIHdpbGwgYmUgcmVzaXplZCB0byB0aGlzIGBoZWlnaHRgLlxuICAgICAqL1xuICAgIGhlaWdodDogbnVtYmVyO1xufVxuXG4vKiogSW1hZ2Ugb3V0cHV0ICovXG5leHBvcnQgZW51bSBJbWdSZXNvbHV0aW9uIHtcbiAgICAvKipcbiAgICAgKiBUaGUgb3V0cHV0IGltYWdlIHdpbGwgYmUgZXF1YWwgdG8gdGhlIGluaXRpYWwgc2l6ZSBvZiB0aGUgY3JvcHBlciBhcmVhLlxuICAgICAqL1xuICAgIERlZmF1bHQsXG4gICAgLyoqIEp1c3QgY3JvcCB0aGUgaW1hZ2Ugd2l0aG91dCByZXNpemluZyAqL1xuICAgIE9yaWdpbmFsSW1hZ2Vcbn1cblxuLyoqIEltYWdlIG91dHB1dCAqL1xuZXhwb3J0IGVudW0gSW1nQ3JvcHBlckVycm9yIHtcbiAgICAvKiogVGhlIGxvYWRlZCBpbWFnZSBleGNlZWRzIHRoZSBzaXplIGxpbWl0IHNldC4gKi9cbiAgICBTaXplLFxuICAgIC8qKiBUaGUgZmlsZSBsb2FkZWQgaXMgbm90IGltYWdlLiAqL1xuICAgIFR5cGUsXG4gICAgLyoqIFdoZW4gdGhlIGltYWdlIGhhcyBub3QgYmVlbiBsb2FkZWQuICovXG4gICAgT3RoZXJcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJbWdDcm9wcGVyRXZlbnQge1xuICAgIC8qKiBDcm9wcGVkIGltYWdlIGRhdGEgVVJMICovXG4gICAgZGF0YVVSTD86IHN0cmluZztcbiAgICBuYW1lOiBzdHJpbmcgfCBudWxsO1xuICAgIC8qKiBGaWxldHlwZSAqL1xuICAgIHR5cGU/OiBzdHJpbmc7XG4gICAgLyoqIENyb3BwZWQgYXJlYSB3aWR0aCAqL1xuICAgIGFyZWFXaWR0aDogbnVtYmVyO1xuICAgIC8qKiBDcm9wcGVkIGFyZWEgaGVpZ2h0ICovXG4gICAgYXJlYUhlaWdodDogbnVtYmVyO1xuICAgIC8qKiBDcm9wcGVkIGltYWdlIHdpZHRoICovXG4gICAgd2lkdGg6IG51bWJlcjtcbiAgICAvKiogQ3JvcHBlZCBpbWFnZSBoZWlnaHQgKi9cbiAgICBoZWlnaHQ6IG51bWJlcjtcbiAgICAvKiogT3JpZ2luYWwgSW1hZ2UgZGF0YSBVUkwgKi9cbiAgICBvcmlnaW5hbERhdGFVUkw/OiBzdHJpbmc7XG4gICAgc2NhbGU6IG51bWJlcjtcbiAgICAvKiogQ3VycmVudCByb3RhdGlvbiBpbiBkZWdyZWVzICovXG4gICAgcm90YXRpb246IG51bWJlcjtcbiAgICAvKiogU2l6ZSBvZiB0aGUgaW1hZ2UgaW4gYnl0ZXMgKi9cbiAgICBzaXplOiBudW1iZXI7XG4gICAgLyoqIFNjYWxlZCBvZmZzZXQgZnJvbSB0aGUgbGVmdCBlZGdlIG9mIHRoZSBpbWFnZSAqL1xuICAgIGxlZnQ6IG51bWJlcjtcbiAgICAvKiogU2NhbGVkIG9mZnNldCBmcm9tIHRoZSB0b3AgZWRnZSBvZiB0aGUgaW1hZ2UgKi9cbiAgICB0b3A6IG51bWJlcjtcbiAgICAvKipcbiAgICAgKiBTY2FsZWQgb2Zmc2V0IGZyb20gdGhlIGxlZnQgZWRnZSBvZiB0aGUgaW1hZ2UgdG8gY2VudGVyIG9mIGFyZWFcbiAgICAgKiBDYW4gYmUgdXNlZCB0byBzZXQgaW1hZ2UgcG9zaXRpb25cbiAgICAgKi9cbiAgICB4T3JpZ2luOiBudW1iZXI7XG4gICAgLyoqXG4gICAgICogU2NhbGVkIG9mZnNldCBmcm9tIHRoZSB0b3AgZWRnZSBvZiB0aGUgaW1hZ2UgdG8gY2VudGVyIG9mIGFyZWFcbiAgICAgKiBDYW4gYmUgdXNlZCB0byBzZXQgaW1hZ2UgcG9zaXRpb25cbiAgICAgKi9cbiAgICB5T3JpZ2luOiBudW1iZXI7XG4gICAgLyoqIEBkZXByZWNhdGVkIFVzZSBgeE9yaWdpbiAmIHlPcmlnaW5gIGluc3RlYWQuICovXG4gICAgcG9zaXRpb24/OiB7XG4gICAgICAgIHg6IG51bWJlclxuICAgICAgICB5OiBudW1iZXJcbiAgICB9O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEltZ0Nyb3BwZXJFcnJvckV2ZW50IHtcbiAgICBuYW1lPzogc3RyaW5nO1xuICAgIC8qKiBTaXplIG9mIHRoZSBpbWFnZSBpbiBieXRlcyAqL1xuICAgIHNpemU6IG51bWJlcjtcbiAgICAvKiogRmlsZXR5cGUgKi9cbiAgICB0eXBlOiBzdHJpbmc7XG4gICAgLyoqIFR5cGUgb2YgZXJyb3IgKi9cbiAgICBlcnJvcjogSW1nQ3JvcHBlckVycm9yO1xuICAgIGVycm9yTXNnPzogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgSW1nUmVjdCB7XG4gICAgeDogbnVtYmVyO1xuICAgIHk6IG51bWJlcjtcbiAgICB4YzogbnVtYmVyO1xuICAgIHljOiBudW1iZXI7XG4gICAgLyoqIHRyYW5zZm9ybSB3aXRoICovXG4gICAgd3Q6IG51bWJlcjtcbiAgICBodDogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEltZ0Nyb3BwZXJMb2FkZXJDb25maWcge1xuICAgIG5hbWU/OiBzdHJpbmcgfCBudWxsO1xuICAgIC8qKiBGaWxldHlwZSAqL1xuICAgIHR5cGU/OiBzdHJpbmc7XG4gICAgLyoqIENyb3BwZWQgYXJlYSB3aWR0aCAqL1xuICAgIGFyZWFXaWR0aD86IG51bWJlcjtcbiAgICAvKiogQ3JvcHBlZCBhcmVhIGhlaWdodCAqL1xuICAgIGFyZWFIZWlnaHQ/OiBudW1iZXI7XG4gICAgLyoqIENyb3BwZWQgaW1hZ2Ugd2lkdGggKi9cbiAgICB3aWR0aD86IG51bWJlcjtcbiAgICAvKiogQ3JvcHBlZCBpbWFnZSBoZWlnaHQgKi9cbiAgICBoZWlnaHQ/OiBudW1iZXI7XG4gICAgLyoqIE9yaWdpbmFsIEltYWdlIGRhdGEgVVJMICovXG4gICAgb3JpZ2luYWxEYXRhVVJMOiBzdHJpbmc7XG4gICAgc2NhbGU/OiBudW1iZXI7XG4gICAgLyoqIEN1cnJlbnQgcm90YXRpb24gaW4gZGVncmVlcyAqL1xuICAgIHJvdGF0aW9uPzogbnVtYmVyO1xuICAgIC8qKiBTaXplIG9mIHRoZSBpbWFnZSBpbiBieXRlcyAqL1xuICAgIHNpemU/OiBudW1iZXI7XG4gICAgLyoqIE9mZnNldCBmcm9tIHRoZSBsZWZ0IGVkZ2Ugb2YgdGhlIGltYWdlIHRvIGNlbnRlciBvZiBhcmVhICovXG4gICAgeE9yaWdpbj86IG51bWJlcjtcbiAgICAvKiogT2Zmc2V0IGZyb20gdGhlIHRvcCBlZGdlIG9mIHRoZSBpbWFnZSB0byBjZW50ZXIgb2YgYXJlYSAqL1xuICAgIHlPcmlnaW4/OiBudW1iZXI7XG59XG5cbkBDb21wb25lbnQoe1xuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICAgIHByZXNlcnZlV2hpdGVzcGFjZXM6IGZhbHNlLFxuICAgIHNlbGVjdG9yOiBcIm5pY2UtaW1nLWNyb3BwZXIsIG5pY2UtaW1hZ2UtY3JvcHBlclwiLFxuICAgIHRlbXBsYXRlVXJsOiBcImltYWdlLWNyb3BwZXIudGVtcGxhdGUuaHRtbFwiLFxuICAgIHN0eWxlVXJsczogW1wiaW1hZ2UtY3JvcHBlci5zdHlsZS5zY3NzXCJdLFxuICAgIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmVcbn0pXG5leHBvcnQgY2xhc3MgTmljZUltYWdlQ3JvcHBlckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgICBzdGF0aWMgcmVhZG9ubHkg0LggPSBcIk5pY2VJbWFnZUNyb3BwZXJcIjtcblxuICAgIHByaXZhdGUgX2N1cnJlbnRMb2FkQ29uZmlnPzogSW1nQ3JvcHBlckxvYWRlckNvbmZpZztcblxuICAgIC8qKiBPcmlnaW5hbCBpbWFnZSAqL1xuICAgIHByaXZhdGUgX2ltZzogSFRNTEltYWdlRWxlbWVudDtcbiAgICBwcml2YXRlIG9mZnNldD86IHtcbiAgICAgICAgeDogbnVtYmVyXG4gICAgICAgIHk6IG51bWJlclxuICAgICAgICBsZWZ0OiBudW1iZXJcbiAgICAgICAgdG9wOiBudW1iZXJcbiAgICB9O1xuICAgIHByaXZhdGUgX3NjYWxlPzogbnVtYmVyO1xuICAgIHByaXZhdGUgX3NjYWwzRml4PzogbnVtYmVyO1xuICAgIHByaXZhdGUgX21pblNjYWxlPzogbnVtYmVyO1xuICAgIHByaXZhdGUgX21heFNjYWxlPzogbnVtYmVyO1xuICAgIC8qKiBJbml0aWFsIGNvbmZpZyAqL1xuICAgIHByaXZhdGUgX2NvbmZpZ1ByaW1hcnk6IEltZ0Nyb3BwZXJDb25maWc7XG4gICAgcHJpdmF0ZSBfY29uZmlnOiBJbWdDcm9wcGVyQ29uZmlnO1xuICAgIHByaXZhdGUgX2ltZ1JlY3Q6IEltZ1JlY3QgPSB7fSBhcyBhbnk7XG4gICAgcHJpdmF0ZSBfcm90YXRpb24gPSAwO1xuICAgIC8vIHByaXZhdGUgX3NpemVJbkJ5dGVzOiBudW1iZXIgfCBudWxsO1xuICAgIHByaXZhdGUgX2lzU2xpZGluZzogYm9vbGVhbjtcbiAgICAvKiogS2VlcHMgdHJhY2sgb2YgdGhlIGxhc3QgcG9pbnRlciBldmVudCB0aGF0IHdhcyBjYXB0dXJlZCBieSB0aGUgY3JvcCBhcmVhLiAqL1xuICAgIHByaXZhdGUgX2xhc3RQb2ludGVyRXZlbnQ6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50IHwgbnVsbDtcbiAgICBwcml2YXRlIF9zdGFydFBvaW50ZXJFdmVudDoge1xuICAgICAgICB4OiBudW1iZXJcbiAgICAgICAgeTogbnVtYmVyXG4gICAgfSB8IG51bGw7XG4gICAgcHVibGljIF9wcmltYXJ5QXJlYVdpZHRoOiBudW1iZXI7XG4gICAgcHVibGljIF9wcmltYXJ5QXJlYUhlaWdodDogbnVtYmVyO1xuXG4gICAgcHVibGljIF9hYnNvbHV0ZVNjYWxlOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBXaGVuIGlzIGxvYWRlZCBpbWFnZVxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHB1YmxpYyBfaXNMb2FkZWRJbWc6IGJvb2xlYW47XG5cbiAgICAvKiogV2hlbiBpcyBsb2FkZWQgaW1hZ2UgJiByZWFkeSBmb3IgY3JvcCAqL1xuICAgIHB1YmxpYyBpc0xvYWRlZDogYm9vbGVhbjtcbiAgICAvKiogV2hlbiB0aGUgY3JvcHBlciBpcyByZWFkeSB0byBiZSBpbnRlcmFjdGVkICAqL1xuICAgIHB1YmxpYyBpc1JlYWR5OiBib29sZWFuO1xuICAgIHB1YmxpYyBpc0Nyb3BwZWQ6IGJvb2xlYW47XG5cbiAgICBAVmlld0NoaWxkKFwiX2ltZ0NvbnRhaW5lclwiLCB7IHN0YXRpYzogdHJ1ZSB9KVxuICAgIHByaXZhdGUgX2ltZ0NvbnRhaW5lcjogRWxlbWVudFJlZjtcblxuICAgIEBWaWV3Q2hpbGQoXCJfYXJlYVwiLCB7IHJlYWQ6IEVsZW1lbnRSZWYgfSlcbiAgICBwcml2YXRlIF9hcmVhUmVmOiBFbGVtZW50UmVmO1xuICAgIEBWaWV3Q2hpbGQoXCJfaW1nQ2FudmFzXCIsIHsgc3RhdGljOiB0cnVlIH0pXG4gICAgcHJpdmF0ZSBfaW1nQ2FudmFzOiBFbGVtZW50UmVmPEhUTUxDYW52YXNFbGVtZW50PjtcblxuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHNldCBjb25maWcodmFsOiBJbWdDcm9wcGVyQ29uZmlnKSB7XG4gICAgICAgIHRoaXMuX2NvbmZpZyA9IG1lcmdlRGVlcCh7fSwgbmV3IEltZ0Nyb3BwZXJDb25maWcoKSwgdmFsKTtcbiAgICAgICAgdGhpcy5fY29uZmlnUHJpbWFyeSA9IG1lcmdlRGVlcCh7fSwgdGhpcy5fY29uZmlnKTtcbiAgICAgICAgdGhpcy5fcHJpbWFyeUFyZWFXaWR0aCA9IHRoaXMuY29uZmlnLndpZHRoO1xuICAgICAgICB0aGlzLl9wcmltYXJ5QXJlYUhlaWdodCA9IHRoaXMuY29uZmlnLmhlaWdodDtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5fY29uZmlnLnJvdW5kXG4gICAgICAgICAgICAmJiB0aGlzLmNvbmZpZy53aWR0aCAhPT0gdGhpcy5jb25maWcuaGVpZ2h0XG4gICAgICAgICkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke05pY2VJbWFnZUNyb3BwZXJDb21wb25lbnQu0Lh9OiBCb3RoIHdpZHRoIGFuZCBoZWlnaHQgbXVzdCBiZSBlcXVhbCB3aGVuIHVzaW5nIFxcYEltZ0Nyb3BwZXJDb25maWcucm91bmQgPSB0cnVlXFxgYCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbWF4RmlsZVNpemUgPSB0aGlzLl9jb25maWcubWF4RmlsZVNpemU7XG4gICAgICAgIGlmIChtYXhGaWxlU2l6ZSkge1xuICAgICAgICAgICAgdGhpcy5tYXhGaWxlU2l6ZSA9IG1heEZpbGVTaXplO1xuICAgICAgICB9XG4gICAgfVxuICAgIHB1YmxpYyBnZXQgY29uZmlnKCk6IEltZ0Nyb3BwZXJDb25maWcge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29uZmlnO1xuICAgIH1cbiAgICAvKiogU2V0IHNjYWxlICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgc2V0IHNjYWxlKHZhbDogbnVtYmVyIHwgdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuc2V0U2NhbGUodmFsKTtcbiAgICB9XG4gICAgcHVibGljIGdldCBzY2FsZSgpOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2NhbGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRW1pdCBldmVudCBgZXJyb3JgIGlmIHRoZSBmaWxlIHNpemUgZm9yIHRoZSBsaW1pdC5cbiAgICAgKiBOb3RlOiBJdCBvbmx5IHdvcmtzIHdoZW4gdGhlIGltYWdlIGlzIHJlY2VpdmVkIGZyb20gdGhlIGA8aW5wdXQ+YCBldmVudC5cbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBtYXhGaWxlU2l6ZTogbnVtYmVyO1xuXG4gICAgLyoqIEdldCBtaW4gc2NhbGUgKi9cbiAgICBwdWJsaWMgZ2V0IG1pblNjYWxlKCk6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gICAgICAgIHJldHVybiB0aGlzLl9taW5TY2FsZTtcbiAgICB9XG5cbiAgICBAT3V0cHV0KClcbiAgICBwcml2YXRlIHJlYWRvbmx5IHNjYWxlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG5cbiAgICAvKiogRW1pdHMgbWluaW11bSBzdXBwb3J0ZWQgaW1hZ2Ugc2NhbGUgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tb3V0cHV0LXJlbmFtZVxuICAgIEBPdXRwdXQoXCJtaW5TY2FsZVwiKVxuICAgIHByaXZhdGUgcmVhZG9ubHkgbWluU2NhbGVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcblxuICAgIC8qKiBFbWl0cyBtYXhpbXVtIHN1cHBvcnRlZCBpbWFnZSBzY2FsZSAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1vdXRwdXQtcmVuYW1lXG4gICAgQE91dHB1dChcIm1heFNjYWxlXCIpXG4gICAgcHJpdmF0ZSByZWFkb25seSBtYXhTY2FsZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuXG4gICAgLyoqIEVtaXRzIHdoZW4gdGhlIGltYWdlIGlzIGxvYWRlZCAqL1xuICAgIEBPdXRwdXQoKVxuICAgIHByaXZhdGUgcmVhZG9ubHkgaW1hZ2VMb2FkZWQgPSBuZXcgRXZlbnRFbWl0dGVyPEltZ0Nyb3BwZXJFdmVudD4oKTtcblxuICAgIC8qKiBFbWl0cyB3aGVuIHRoZSBjcm9wcGVyIGlzIHJlYWR5IHRvIGJlIGludGVyYWN0ZWQgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJlYWR5ID0gbmV3IEV2ZW50RW1pdHRlcjxJbWdDcm9wcGVyRXZlbnQ+KCk7XG5cbiAgICAvKiogT24gY3JvcCBuZXcgaW1hZ2UgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNyb3BwZWQgPSBuZXcgRXZlbnRFbWl0dGVyPEltZ0Nyb3BwZXJFdmVudD4oKTtcblxuICAgIC8qKiBFbWl0cyB3aGVuIHRoZSBjcm9wcGVyIGlzIGNsZWFuZWQgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNsZWFuZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgICAvKiogRW1pdCBhbiBlcnJvciB3aGVuIHRoZSBsb2FkZWQgaW1hZ2UgaXMgbm90IHZhbGlkICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOiBuby1vdXRwdXQtbmF0aXZlXG4gICAgQE91dHB1dCgpXG4gICAgcHJpdmF0ZSByZWFkb25seSBlcnJvciA9IG5ldyBFdmVudEVtaXR0ZXI8SW1nQ3JvcHBlckVycm9yRXZlbnQ+KCk7XG5cbiAgICBwcml2YXRlIF9jdXJyZW50SW5wdXRFbGVtZW50PzogSFRNTElucHV0RWxlbWVudDtcblxuICAgIC8qKiBFbWl0cyB3aGVuZXZlciB0aGUgY29tcG9uZW50IGlzIGRlc3Ryb3llZC4gKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IF9kZXN0cm95ID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICAgIC8qKiBVc2VkIHRvIHN1YnNjcmliZSB0byBnbG9iYWwgbW92ZSBhbmQgZW5kIGV2ZW50cyAqL1xuICAgIHByb3RlY3RlZCBfZG9jdW1lbnQ6IERvY3VtZW50O1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgX3JlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgICAgIHJlYWRvbmx5IF9lbGVtZW50UmVmOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PixcbiAgICAgICAgcHJpdmF0ZSBjZDogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgICAgIHByaXZhdGUgX25nWm9uZTogTmdab25lLFxuICAgICAgICBASW5qZWN0KERPQ1VNRU5UKSBfZG9jdW1lbnQ6IGFueSxcbiAgICAgICAgdmlld1BvcnRSdWxlcjogVmlld3BvcnRSdWxlclxuICAgICkge1xuICAgICAgICB0aGlzLl9kb2N1bWVudCA9IF9kb2N1bWVudDtcbiAgICAgICAgdmlld1BvcnRSdWxlci5jaGFuZ2UoKVxuICAgICAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3kpKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgoKSA9PlxuICAgICAgICAgICAgICAgIHRoaXMuX25nWm9uZS5ydW4oKCkgPT4gdGhpcy51cGRhdGVDcm9wcGVyUG9zaXRpb24oKSlcbiAgICAgICAgICAgICk7XG4gICAgfVxuXG4gICAgcHVibGljIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLl9uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuX2ltZ0NvbnRhaW5lci5uYXRpdmVFbGVtZW50O1xuICAgICAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwibW91c2Vkb3duXCIsIHRoaXMuX3BvaW50ZXJEb3duLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgICAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hzdGFydFwiLCB0aGlzLl9wb2ludGVyRG93biwgYWN0aXZlRXZlbnRPcHRpb25zKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgICAgICB0aGlzLl9kZXN0cm95Lm5leHQoKTtcbiAgICAgICAgdGhpcy5fZGVzdHJveS5jb21wbGV0ZSgpO1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5faW1nQ29udGFpbmVyLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgIHRoaXMuX2xhc3RQb2ludGVyRXZlbnQgPSBudWxsO1xuICAgICAgICB0aGlzLl9yZW1vdmVHbG9iYWxFdmVudHMoKTtcbiAgICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2Vkb3duXCIsIHRoaXMuX3BvaW50ZXJEb3duLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ0b3VjaHN0YXJ0XCIsIHRoaXMuX3BvaW50ZXJEb3duLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgIH1cblxuICAgIC8qKiBMb2FkIGltYWdlIHdpdGggY2FudmFzICovXG4gICAgcHJpdmF0ZSBfaW1nTG9hZGVkKGltZ0VsZW1lbnQ6IEhUTUxJbWFnZUVsZW1lbnQpOiB2b2lkIHtcbiAgICAgICAgaWYgKGltZ0VsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX2ltZyA9IGltZ0VsZW1lbnQ7XG4gICAgICAgICAgICBjb25zdCBjYW52YXMgPSB0aGlzLl9pbWdDYW52YXMubmF0aXZlRWxlbWVudDtcbiAgICAgICAgICAgIGNhbnZhcy53aWR0aCA9IGltZ0VsZW1lbnQud2lkdGg7XG4gICAgICAgICAgICBjYW52YXMuaGVpZ2h0ID0gaW1nRWxlbWVudC5oZWlnaHQ7XG4gICAgICAgICAgICBjb25zdCBjdHggPSBjYW52YXMuZ2V0Q29udGV4dChcIjJkXCIpO1xuICAgICAgICAgICAgY3R4LmNsZWFyUmVjdCgwLCAwLCBpbWdFbGVtZW50LndpZHRoLCBpbWdFbGVtZW50LmhlaWdodCk7XG4gICAgICAgICAgICBjdHguZHJhd0ltYWdlKGltZ0VsZW1lbnQsIDAsIDApO1xuXG4gICAgICAgICAgICAvKiogc2V0IG1pbiBzY2FsZSAqL1xuICAgICAgICAgICAgdGhpcy5fdXBkYXRlTWluU2NhbGUoY2FudmFzKTtcbiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZU1heFNjYWxlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIF9zZXRTdHlsZXNGb3JDb250SW1nKHZhbHVlczogeyB4PzogbnVtYmVyLCB5PzogbnVtYmVyIH0pIHtcbiAgICAgICAgY29uc3QgbmV3U3R5bGVzID0geyB9IGFzIGFueTtcbiAgICAgICAgaWYgKHZhbHVlcy54ICE9IG51bGwgJiYgdmFsdWVzLnkgIT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc3Qgcm9vdFJlY3QgPSB0aGlzLl9yb290UmVjdCgpO1xuICAgICAgICAgICAgY29uc3QgeCA9IHJvb3RSZWN0LndpZHRoIC8gMiAtICh2YWx1ZXMueCk7XG4gICAgICAgICAgICBjb25zdCB5ID0gcm9vdFJlY3QuaGVpZ2h0IC8gMiAtICh2YWx1ZXMueSk7XG5cbiAgICAgICAgICAgIHRoaXMuX2ltZ1JlY3QueCA9ICh2YWx1ZXMueCk7XG4gICAgICAgICAgICB0aGlzLl9pbWdSZWN0LnkgPSAodmFsdWVzLnkpO1xuICAgICAgICAgICAgdGhpcy5faW1nUmVjdC54YyA9ICh4KTtcbiAgICAgICAgICAgIHRoaXMuX2ltZ1JlY3QueWMgPSAoeSk7XG5cbiAgICAgICAgfVxuICAgICAgICBuZXdTdHlsZXMudHJhbnNmb3JtID0gYHRyYW5zbGF0ZTNkKCR7KHRoaXMuX2ltZ1JlY3QueCl9cHgsJHsodGhpcy5faW1nUmVjdC55KX1weCwgMClgO1xuICAgICAgICBuZXdTdHlsZXMudHJhbnNmb3JtICs9IGBzY2FsZSgke3RoaXMuX3NjYWwzRml4fSlgO1xuICAgICAgICBuZXdTdHlsZXMudHJhbnNmb3JtT3JpZ2luID0gYCR7dGhpcy5faW1nUmVjdC54Y31weCAke3RoaXMuX2ltZ1JlY3QueWN9cHggMGA7XG4gICAgICAgIG5ld1N0eWxlc1tcIi13ZWJraXQtdHJhbnNmb3JtXCJdID0gbmV3U3R5bGVzLnRyYW5zZm9ybTtcbiAgICAgICAgbmV3U3R5bGVzW1wiLXdlYmtpdC10cmFuc2Zvcm0tb3JpZ2luXCJdID0gbmV3U3R5bGVzLnRyYW5zZm9ybU9yaWdpbjtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gbmV3U3R5bGVzKSB7XG4gICAgICAgICAgICBpZiAobmV3U3R5bGVzLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9yZW5kZXJlci5zZXRTdHlsZSh0aGlzLl9pbWdDb250YWluZXIubmF0aXZlRWxlbWVudCwga2V5LCBuZXdTdHlsZXNba2V5XSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVXBkYXRlIGFyZWEgYW5kIGltYWdlIHBvc2l0aW9uIG9ubHkgaWYgbmVlZGVkLFxuICAgICAqIHRoaXMgaXMgdXNlZCB3aGVuIHdpbmRvdyByZXNpemVcbiAgICAgKi9cbiAgICBwdWJsaWMgdXBkYXRlQ3JvcHBlclBvc2l0aW9uKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5pc0xvYWRlZCkge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVQb3NpdGlvbigpO1xuICAgICAgICAgICAgdGhpcy5fdXBkYXRlQXJlYUlmTmVlZGVkKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogTG9hZCBJbWFnZSBmcm9tIGlucHV0IGV2ZW50ICovXG4gICAgcHVibGljIHNlbGVjdElucHV0RXZlbnQoaW1nOiBFdmVudCkge1xuICAgICAgICB0aGlzLl9jdXJyZW50SW5wdXRFbGVtZW50ID0gaW1nLnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50O1xuICAgICAgICBjb25zdCBfaW1nID0gaW1nLnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50O1xuICAgICAgICBpZiAoX2ltZy5maWxlcyAmJiBfaW1nLmZpbGVzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGZpbGVTaXplID0gX2ltZy5maWxlc1swXS5zaXplO1xuICAgICAgICBjb25zdCBmaWxlTmFtZSA9IF9pbWcudmFsdWUucmVwbGFjZSgvLiooXFwvfFxcXFwpLywgXCJcIik7XG5cbiAgICAgICAgaWYgKHRoaXMubWF4RmlsZVNpemUgJiYgZmlsZVNpemUgPiB0aGlzLm1heEZpbGVTaXplKSB7XG4gICAgICAgICAgICBjb25zdCBjcm9wRXZlbnQ6IEltZ0Nyb3BwZXJFcnJvckV2ZW50ID0ge1xuICAgICAgICAgICAgICAgIG5hbWU6IGZpbGVOYW1lLFxuICAgICAgICAgICAgICAgIHR5cGU6IF9pbWcuZmlsZXNbMF0udHlwZSxcbiAgICAgICAgICAgICAgICBzaXplOiBmaWxlU2l6ZSxcbiAgICAgICAgICAgICAgICBlcnJvcjogSW1nQ3JvcHBlckVycm9yLlNpemVcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLmNsZWFuKCk7XG4gICAgICAgICAgICB0aGlzLmVycm9yLmVtaXQoY3JvcEV2ZW50IGFzIEltZ0Nyb3BwZXJFcnJvckV2ZW50KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIG5ldyBPYnNlcnZhYmxlPFByb2dyZXNzRXZlbnQ+KG9ic2VydmVyID0+IHtcblxuICAgICAgICAgICAgY29uc3QgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcblxuICAgICAgICAgICAgcmVhZGVyLm9uZXJyb3IgPSBlcnIgPT4gb2JzZXJ2ZXIuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgIHJlYWRlci5vbmFib3J0ID0gZXJyID0+IG9ic2VydmVyLmVycm9yKGVycik7XG4gICAgICAgICAgICByZWFkZXIub25sb2FkID0gKGV2KSA9PiBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KGV2KTtcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHJlYWRlci5yZWFkQXNEYXRhVVJMKF9pbWcuZmlsZXNbMF0pO1xuICAgICAgICB9KVxuICAgICAgICAgICAgLnBpcGUodGFrZSgxKSwgdGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3kpKVxuICAgICAgICAgICAgLnN1YnNjcmliZShcbiAgICAgICAgICAgICAgICAobG9hZEV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9yaWdpbmFsRGF0YVVSTCA9IChsb2FkRXZlbnQudGFyZ2V0IGFzIEZpbGVSZWFkZXIpLnJlc3VsdCBhcyBzdHJpbmc7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2FkSW1hZ2Uoe1xuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogZmlsZU5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBzaXplOiBfaW1nLmZpbGVzWzBdLnNpemUsIC8vIHNpemUgaW4gYnl0ZXNcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IHRoaXMuY29uZmlnLnR5cGUgfHwgX2ltZy5maWxlc1swXS50eXBlLFxuICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxEYXRhVVJMXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNyb3BFdmVudDogSW1nQ3JvcHBlckVycm9yRXZlbnQgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBmaWxlTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpemU6IGZpbGVTaXplLFxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3I6IEltZ0Nyb3BwZXJFcnJvci5PdGhlcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTXNnOiBcIlRoZSBGaWxlIGNvdWxkIG5vdCBiZSBsb2FkZWQuXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBfaW1nLmZpbGVzWzBdLnR5cGVcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jbGVhbigpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9yLmVtaXQoY3JvcEV2ZW50IGFzIEltZ0Nyb3BwZXJFcnJvckV2ZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuXG4gICAgfVxuXG4gICAgLyoqIFNldCB0aGUgc2l6ZSBvZiB0aGUgaW1hZ2UsIHRoZSB2YWx1ZXMgY2FuIGJlIDAgYmV0d2VlbiAxLCB3aGVyZSAxIGlzIHRoZSBvcmlnaW5hbCBzaXplICovXG4gICAgcHVibGljIHNldFNjYWxlKHNpemU/OiBudW1iZXIsIG5vQXV0b0Nyb3A/OiBib29sZWFuKSB7XG4gICAgICAgIC8vIGZpeCBtaW4gc2NhbGVcbiAgICAgICAgY29uc3QgbmV3U2l6ZSA9IHNpemUgPj0gdGhpcy5taW5TY2FsZSAmJiBzaXplIDw9IDEgPyBzaXplIDogdGhpcy5taW5TY2FsZTtcblxuICAgICAgICAvLyBjaGVja1xuICAgICAgICBjb25zdCBjaGFuZ2VkID0gc2l6ZSAhPSBudWxsICYmIHNpemUgIT09IHRoaXMuc2NhbGUgJiYgbmV3U2l6ZSAhPT0gdGhpcy5zY2FsZTtcbiAgICAgICAgdGhpcy5fc2NhbGUgPSBzaXplO1xuICAgICAgICBpZiAoIWNoYW5nZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9zY2FsM0ZpeCA9IG5ld1NpemU7XG4gICAgICAgIHRoaXMuX3VwZGF0ZUFic29sdXRlU2NhbGUoKTtcbiAgICAgICAgaWYgKHRoaXMuaXNMb2FkZWQpIHtcbiAgICAgICAgICAgIGlmIChjaGFuZ2VkKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3JpZ2luUG9zaXRpb24gPSB7Li4udGhpcy5faW1nUmVjdH07XG4gICAgICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSB7XG4gICAgICAgICAgICAgICAgICAgIHg6IG9yaWdpblBvc2l0aW9uLngsXG4gICAgICAgICAgICAgICAgICAgIHk6IG9yaWdpblBvc2l0aW9uLnksXG4gICAgICAgICAgICAgICAgICAgIGxlZnQ6IG9yaWdpblBvc2l0aW9uLnhjLFxuICAgICAgICAgICAgICAgICAgICB0b3A6IG9yaWdpblBvc2l0aW9uLnljXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLl9zZXRTdHlsZXNGb3JDb250SW1nKHt9KTtcbiAgICAgICAgICAgICAgICB0aGlzLl9zaW11bGF0ZVBvaW50ZXJNb3ZlKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLm1pblNjYWxlKSB7XG4gICAgICAgICAgICB0aGlzLl9zZXRTdHlsZXNGb3JDb250SW1nKHtcbiAgICAgICAgICAgICAgICAuLi50aGlzLl9nZXRDZW50ZXJQb2ludHMoKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnNjYWxlQ2hhbmdlLmVtaXQoc2l6ZSk7XG4gICAgICAgIGlmICghbm9BdXRvQ3JvcCkge1xuICAgICAgICAgICAgdGhpcy5fY3JvcElmQXV0b0Nyb3AoKTtcbiAgICAgICAgfVxuXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfZ2V0Q2VudGVyUG9pbnRzKCkge1xuICAgICAgICBjb25zdCByb290ID0gdGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50IGFzIEhUTUxFbGVtZW50O1xuICAgICAgICBjb25zdCBpbWcgPSB0aGlzLl9pbWdDYW52YXMubmF0aXZlRWxlbWVudDtcbiAgICAgICAgY29uc3QgeCA9IChyb290Lm9mZnNldFdpZHRoIC0gKGltZy53aWR0aCkpIC8gMjtcbiAgICAgICAgY29uc3QgeSA9IChyb290Lm9mZnNldEhlaWdodCAtIChpbWcuaGVpZ2h0KSkgLyAyO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeCxcbiAgICAgICAgICAgIHlcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGaXQgdG8gc2NyZWVuXG4gICAgICovXG4gICAgcHVibGljIGZpdFRvU2NyZWVuKCkge1xuICAgICAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgICAgIGNvbnN0IG1pbiA9IHtcbiAgICAgICAgICAgIHdpZHRoOiBjb250YWluZXIub2Zmc2V0V2lkdGgsXG4gICAgICAgICAgICBoZWlnaHQ6IGNvbnRhaW5lci5vZmZzZXRIZWlnaHRcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgeyB3aWR0aCwgaGVpZ2h0IH0gPSB0aGlzLl9pbWc7XG4gICAgICAgIGNvbnN0IG1pblNjYWxlID0ge1xuICAgICAgICAgICAgd2lkdGg6IG1pbi53aWR0aCAvIHdpZHRoLFxuICAgICAgICAgICAgaGVpZ2h0OiBtaW4uaGVpZ2h0IC8gaGVpZ2h0XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IE1hdGgubWF4KG1pblNjYWxlLndpZHRoLCBtaW5TY2FsZS5oZWlnaHQpO1xuICAgICAgICB0aGlzLnNldFNjYWxlKHJlc3VsdCk7XG4gICAgfVxuXG4gICAgcHVibGljIGZpdCgpIHtcbiAgICAgICAgdGhpcy5zZXRTY2FsZSh0aGlzLm1pblNjYWxlKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9wb2ludGVyRG93biA9IChldmVudDogVG91Y2hFdmVudCB8IE1vdXNlRXZlbnQpID0+IHtcbiAgICAgICAgLy8gRG9uJ3QgZG8gYW55dGhpbmcgaWYgdGhlXG4gICAgICAgIC8vIHVzZXIgaXMgdXNpbmcgYW55dGhpbmcgb3RoZXIgdGhhbiB0aGUgbWFpbiBtb3VzZSBidXR0b24uXG4gICAgICAgIGlmICh0aGlzLl9pc1NsaWRpbmcgfHwgKCFpc1RvdWNoRXZlbnQoZXZlbnQpICYmIGV2ZW50LmJ1dHRvbiAhPT0gMCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX25nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5faXNTbGlkaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0ge1xuICAgICAgICAgICAgICAgIHg6IHRoaXMuX2ltZ1JlY3QueCxcbiAgICAgICAgICAgICAgICB5OiB0aGlzLl9pbWdSZWN0LnksXG4gICAgICAgICAgICAgICAgbGVmdDogdGhpcy5faW1nUmVjdC54YyxcbiAgICAgICAgICAgICAgICB0b3A6IHRoaXMuX2ltZ1JlY3QueWNcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLl9sYXN0UG9pbnRlckV2ZW50ID0gZXZlbnQ7XG4gICAgICAgICAgICB0aGlzLl9zdGFydFBvaW50ZXJFdmVudCA9IGdldEdlc3R1cmVQb2ludEZyb21FdmVudChldmVudCk7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgdGhpcy5fYmluZEdsb2JhbEV2ZW50cyhldmVudCk7XG4gICAgICAgIH0pO1xuXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2ltdWxhdGUgcG9pbnRlck1vdmUgd2l0aCBjbGllbnRYID0gMCBhbmQgY2xpZW50WSA9IDAsXG4gICAgICogdGhpcyBpcyB1c2VkIGJ5IGBzZXRTY2FsZWAgYW5kIGByb3RhdGVgXG4gICAgICovXG4gICAgcHJpdmF0ZSBfc2ltdWxhdGVQb2ludGVyTW92ZSgpIHtcbiAgICAgICAgdGhpcy5faXNTbGlkaW5nID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5fc3RhcnRQb2ludGVyRXZlbnQgPSB7XG4gICAgICAgICAgICB4OiAwLFxuICAgICAgICAgICAgeTogMFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLl9wb2ludGVyTW92ZSh7XG4gICAgICAgICAgICBjbGllbnRYOiAwLFxuICAgICAgICAgICAgY2xpZW50WTogMCxcbiAgICAgICAgICAgIHR5cGU6IFwiblwiLFxuICAgICAgICAgICAgcHJldmVudERlZmF1bHQ6ICgpID0+IHt9XG4gICAgICAgIH0gYXMgTW91c2VFdmVudCk7XG4gICAgICAgIHRoaXMuX2lzU2xpZGluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9zdGFydFBvaW50ZXJFdmVudCA9IG51bGw7XG4gICAgfVxuXG4gICAgcHVibGljIF9tYXJrRm9yQ2hlY2soKSB7XG4gICAgICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsbGVkIHdoZW4gdGhlIHVzZXIgaGFzIG1vdmVkIHRoZWlyIHBvaW50ZXIgYWZ0ZXJcbiAgICAgKiBzdGFydGluZyB0byBkcmFnLlxuICAgICAqL1xuICAgIHByaXZhdGUgX3BvaW50ZXJNb3ZlID0gKGV2ZW50OiBUb3VjaEV2ZW50IHwgTW91c2VFdmVudCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5faXNTbGlkaW5nKSB7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgdGhpcy5fbGFzdFBvaW50ZXJFdmVudCA9IGV2ZW50O1xuICAgICAgICAgICAgbGV0IHg6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGxldCB5OiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gICAgICAgICAgICBjb25zdCBjYW52YXMgPSB0aGlzLl9pbWdDYW52YXMubmF0aXZlRWxlbWVudDtcbiAgICAgICAgICAgIGNvbnN0IHNjYWxlRml4ID0gdGhpcy5fc2NhbDNGaXg7XG4gICAgICAgICAgICBjb25zdCBjb25maWcgPSB0aGlzLmNvbmZpZztcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0UCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICAgICAgY29uc3QgcG9pbnQgPSBnZXRHZXN0dXJlUG9pbnRGcm9tRXZlbnQoZXZlbnQpO1xuICAgICAgICAgICAgY29uc3QgZGVsdGFYID0gcG9pbnQueCAtIHRoaXMuX3N0YXJ0UG9pbnRlckV2ZW50Lng7XG4gICAgICAgICAgICBjb25zdCBkZWx0YVkgPSBwb2ludC55IC0gdGhpcy5fc3RhcnRQb2ludGVyRXZlbnQueTtcbiAgICAgICAgICAgIGlmICghc2NhbGVGaXggfHwgIXN0YXJ0UCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgaXNNaW5TY2FsZVkgPSBjYW52YXMuaGVpZ2h0ICogc2NhbGVGaXggPCBjb25maWcuaGVpZ2h0ICYmIGNvbmZpZy5leHRyYVpvb21PdXQ7XG4gICAgICAgICAgICBjb25zdCBpc01pblNjYWxlWCA9IGNhbnZhcy53aWR0aCAqIHNjYWxlRml4IDwgY29uZmlnLndpZHRoICYmIGNvbmZpZy5leHRyYVpvb21PdXQ7XG5cbiAgICAgICAgICAgIGNvbnN0IGxpbWl0TGVmdCA9IChjb25maWcud2lkdGggLyAyIC8gc2NhbGVGaXgpID49IHN0YXJ0UC5sZWZ0IC0gKGRlbHRhWCAvIHNjYWxlRml4KTtcbiAgICAgICAgICAgIGNvbnN0IGxpbWl0UmlnaHQgPSAoY29uZmlnLndpZHRoIC8gMiAvIHNjYWxlRml4KSArXG4gICAgICAgICAgICAgICAgKGNhbnZhcy53aWR0aCkgLSAoc3RhcnRQLmxlZnQgLSAoZGVsdGFYIC8gc2NhbGVGaXgpKSA8PSBjb25maWcud2lkdGggLyBzY2FsZUZpeDtcbiAgICAgICAgICAgIGNvbnN0IGxpbWl0VG9wID0gKChjb25maWcuaGVpZ2h0IC8gMiAvIHNjYWxlRml4KSA+PSAoc3RhcnRQLnRvcCAtIChkZWx0YVkgLyBzY2FsZUZpeCkpKTtcbiAgICAgICAgICAgIGNvbnN0IGxpbWl0Qm90dG9tID0gKFxuICAgICAgICAgICAgICAgICgoY29uZmlnLmhlaWdodCAvIDIgLyBzY2FsZUZpeCkgKyAoY2FudmFzLmhlaWdodCkgLSAoc3RhcnRQLnRvcCAtIChkZWx0YVkgLyBzY2FsZUZpeCkpKSA8PSAoY29uZmlnLmhlaWdodCAvIHNjYWxlRml4KVxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgLy8gTGltaXQgZm9yIGxlZnRcbiAgICAgICAgICAgIGlmICgobGltaXRMZWZ0ICYmICFpc01pblNjYWxlWCkgfHwgKCFsaW1pdExlZnQgJiYgaXNNaW5TY2FsZVgpKSB7XG4gICAgICAgICAgICAgICAgeCA9IHN0YXJ0UC54ICsgKHN0YXJ0UC5sZWZ0KSAtIChjb25maWcud2lkdGggLyAyIC8gc2NhbGVGaXgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBMaW1pdCBmb3IgcmlnaHRcbiAgICAgICAgICAgIGlmICgobGltaXRSaWdodCAmJiAhaXNNaW5TY2FsZVgpIHx8ICghbGltaXRSaWdodCAmJiBpc01pblNjYWxlWCkpIHtcbiAgICAgICAgICAgICAgICB4ID0gc3RhcnRQLnggKyAoc3RhcnRQLmxlZnQpICsgKGNvbmZpZy53aWR0aCAvIDIgLyBzY2FsZUZpeCkgLSBjYW52YXMud2lkdGg7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIExpbWl0IGZvciB0b3BcbiAgICAgICAgICAgIGlmICgobGltaXRUb3AgJiYgIWlzTWluU2NhbGVZKSB8fCAoIWxpbWl0VG9wICYmIGlzTWluU2NhbGVZKSkge1xuICAgICAgICAgICAgICAgIHkgPSBzdGFydFAueSArIChzdGFydFAudG9wKSAtIChjb25maWcuaGVpZ2h0IC8gMiAvIHNjYWxlRml4KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gTGltaXQgZm9yIGJvdHRvbVxuICAgICAgICAgICAgaWYgKChsaW1pdEJvdHRvbSAmJiAhaXNNaW5TY2FsZVkpIHx8ICghbGltaXRCb3R0b20gJiYgaXNNaW5TY2FsZVkpKSB7XG4gICAgICAgICAgICAgICAgeSA9IHN0YXJ0UC55ICsgKHN0YXJ0UC50b3ApICsgKGNvbmZpZy5oZWlnaHQgLyAyIC8gc2NhbGVGaXgpIC0gY2FudmFzLmhlaWdodDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gV2hlbiBwcmVzcyBzaGlmdEtleSwgZGVwcmVjYXRlZFxuICAgICAgICAgICAgLy8gaWYgKGV2ZW50LnNyY0V2ZW50ICYmIGV2ZW50LnNyY0V2ZW50LnNoaWZ0S2V5KSB7XG4gICAgICAgICAgICAvLyAgIGlmIChNYXRoLmFicyhldmVudC5kZWx0YVgpID09PSBNYXRoLm1heChNYXRoLmFicyhldmVudC5kZWx0YVgpLCBNYXRoLmFicyhldmVudC5kZWx0YVkpKSkge1xuICAgICAgICAgICAgLy8gICAgIHkgPSB0aGlzLm9mZnNldC50b3A7XG4gICAgICAgICAgICAvLyAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyAgICAgeCA9IHRoaXMub2Zmc2V0LmxlZnQ7XG4gICAgICAgICAgICAvLyAgIH1cbiAgICAgICAgICAgIC8vIH1cblxuICAgICAgICAgICAgaWYgKHggPT09IHZvaWQgMCkgeyB4ID0gKGRlbHRhWCAvIHNjYWxlRml4KSArIChzdGFydFAueCk7IH1cbiAgICAgICAgICAgIGlmICh5ID09PSB2b2lkIDApIHsgeSA9IChkZWx0YVkgLyBzY2FsZUZpeCkgKyAoc3RhcnRQLnkpOyB9XG4gICAgICAgICAgICB0aGlzLl9zZXRTdHlsZXNGb3JDb250SW1nKHtcbiAgICAgICAgICAgICAgICB4LCB5XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyB1cGRhdGVQb3NpdGlvbigpOiB2b2lkO1xuICAgIHB1YmxpYyB1cGRhdGVQb3NpdGlvbih4T3JpZ2luOiBudW1iZXIsIHlPcmlnaW46IG51bWJlcik6IHZvaWQ7XG4gICAgcHVibGljIHVwZGF0ZVBvc2l0aW9uKHhPcmlnaW4/OiBudW1iZXIsIHlPcmlnaW4/OiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgaG9zdFJlY3QgPSB0aGlzLl9yb290UmVjdCgpO1xuICAgICAgICBjb25zdCBhcmVhUmVjdCA9IHRoaXMuX2FyZWFDcm9wcGVyUmVjdCgpO1xuICAgICAgICBjb25zdCBhcmVhV2lkdGggPSBhcmVhUmVjdC53aWR0aCA+IGhvc3RSZWN0LndpZHRoXG4gICAgICAgICAgICA/IGhvc3RSZWN0LndpZHRoXG4gICAgICAgICAgICA6IGFyZWFSZWN0LndpZHRoO1xuICAgICAgICBjb25zdCBhcmVhSGVpZ2h0ID0gYXJlYVJlY3QuaGVpZ2h0ID4gaG9zdFJlY3QuaGVpZ2h0XG4gICAgICAgICAgICA/IGhvc3RSZWN0LmhlaWdodFxuICAgICAgICAgICAgOiBhcmVhUmVjdC5oZWlnaHQ7XG4gICAgICAgIGxldCB4OiBudW1iZXI7XG4gICAgICAgIGxldCB5OiBudW1iZXI7XG4gICAgICAgIGlmICh4T3JpZ2luID09IG51bGwgJiYgeU9yaWdpbiA9PSBudWxsKSB7XG4gICAgICAgICAgICB4T3JpZ2luID0gdGhpcy5faW1nUmVjdC54YztcbiAgICAgICAgICAgIHlPcmlnaW4gPSB0aGlzLl9pbWdSZWN0LnljO1xuICAgICAgICB9XG4gICAgICAgIHggPSAoYXJlYVJlY3QubGVmdCAtIGhvc3RSZWN0LmxlZnQpO1xuICAgICAgICB5ID0gKGFyZWFSZWN0LnRvcCAtIGhvc3RSZWN0LnRvcCk7XG4gICAgICAgIHggLT0gKHhPcmlnaW4gLSAoYXJlYVdpZHRoIC8gMikpO1xuICAgICAgICB5IC09ICh5T3JpZ2luIC0gKGFyZWFIZWlnaHQgLyAyKSk7XG5cbiAgICAgICAgdGhpcy5fc2V0U3R5bGVzRm9yQ29udEltZyh7XG4gICAgICAgICAgICB4LCB5XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBfc2xpZGVFbmQoKSB7XG4gICAgICAgIHRoaXMuX2Nyb3BJZkF1dG9Dcm9wKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfY3JvcElmQXV0b0Nyb3AoKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy5hdXRvQ3JvcCkge1xuICAgICAgICAgICAgdGhpcy5jcm9wKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogKyAqL1xuICAgIHB1YmxpYyB6b29tSW4oKSB7XG4gICAgICAgIGNvbnN0IHNjYWxlID0gdGhpcy5fc2NhbDNGaXggKyAuMDU7XG4gICAgICAgIGlmIChzY2FsZSA+IHRoaXMubWluU2NhbGUgJiYgc2NhbGUgPD0gdGhpcy5fbWF4U2NhbGUpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U2NhbGUoc2NhbGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZXRTY2FsZSh0aGlzLl9tYXhTY2FsZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQ2xlYW4gdGhlIGltZyBjcm9wcGVyICovXG4gICAgcHVibGljIGNsZWFuKCkge1xuICAgICAgICAvLyBmaXggY2hvb3NpbmcgdGhlIHNhbWUgaW1hZ2UgZG9lcyBub3QgbG9hZFxuICAgICAgICBpZiAodGhpcy5fY3VycmVudElucHV0RWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5fY3VycmVudElucHV0RWxlbWVudC52YWx1ZSA9IFwiXCI7XG4gICAgICAgICAgICB0aGlzLl9jdXJyZW50SW5wdXRFbGVtZW50ID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5pc0xvYWRlZCkge1xuICAgICAgICAgICAgdGhpcy5faW1nUmVjdCA9IHsgfSBhcyBhbnk7XG4gICAgICAgICAgICB0aGlzLm9mZnNldCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHRoaXMuc2NhbGUgPSB1bmRlZmluZWQgYXMgYW55O1xuICAgICAgICAgICAgdGhpcy5fc2NhbDNGaXggPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0aGlzLl9yb3RhdGlvbiA9IDA7XG4gICAgICAgICAgICB0aGlzLl9taW5TY2FsZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHRoaXMuX2lzTG9hZGVkSW1nID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLmlzTG9hZGVkID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLmlzQ3JvcHBlZCA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5fY3VycmVudExvYWRDb25maWcgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0aGlzLmNvbmZpZyA9IHRoaXMuX2NvbmZpZ1ByaW1hcnk7XG4gICAgICAgICAgICBjb25zdCBjYW52YXMgPSB0aGlzLl9pbWdDYW52YXMubmF0aXZlRWxlbWVudDtcbiAgICAgICAgICAgIGNhbnZhcy53aWR0aCA9IDA7XG4gICAgICAgICAgICBjYW52YXMuaGVpZ2h0ID0gMDtcbiAgICAgICAgICAgIHRoaXMuY2xlYW5lZC5lbWl0KG51bGwpO1xuICAgICAgICAgICAgdGhpcy5jZC5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiAtICovXG4gICAgcHVibGljIHpvb21PdXQoKSB7XG4gICAgICAgIGNvbnN0IHNjYWxlID0gdGhpcy5fc2NhbDNGaXggLSAuMDU7XG4gICAgICAgIGlmIChzY2FsZSA+IHRoaXMubWluU2NhbGUgJiYgc2NhbGUgPD0gdGhpcy5fbWF4U2NhbGUpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U2NhbGUoc2NhbGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5maXQoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBwdWJsaWMgY2VudGVyKCkge1xuICAgICAgICBjb25zdCBuZXdTdHlsZXMgPSB7XG4gICAgICAgICAgICAuLi50aGlzLl9nZXRDZW50ZXJQb2ludHMoKVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLl9zZXRTdHlsZXNGb3JDb250SW1nKG5ld1N0eWxlcyk7XG4gICAgICAgIHRoaXMuX2Nyb3BJZkF1dG9Dcm9wKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGxvYWQgYW4gaW1hZ2UgZnJvbSBhIGdpdmVuIGNvbmZpZ3VyYXRpb24sXG4gICAgICogb3IgZnJvbSB0aGUgcmVzdWx0IG9mIGEgY3JvcHBlZCBpbWFnZVxuICAgICAqL1xuICAgIHB1YmxpYyBsb2FkSW1hZ2UoY29uZmlnOiBJbWdDcm9wcGVyTG9hZGVyQ29uZmlnIHwgc3RyaW5nLCBmbj86ICgpID0+IHZvaWQpIHtcbiAgICAgICAgdGhpcy5jbGVhbigpO1xuICAgICAgICBjb25zdCBfY29uZmlnID0gdGhpcy5fY3VycmVudExvYWRDb25maWcgPSB0eXBlb2YgY29uZmlnID09PSBcInN0cmluZ1wiXG4gICAgICAgICAgICA/IHsgb3JpZ2luYWxEYXRhVVJMOiBjb25maWcgfVxuICAgICAgICAgICAgOiB7IC4uLmNvbmZpZyB9O1xuICAgICAgICBsZXQgc3JjID0gX2NvbmZpZy5vcmlnaW5hbERhdGFVUkw7XG4gICAgICAgIHRoaXMuX3ByaW1hcnlBcmVhV2lkdGggPSB0aGlzLl9jb25maWdQcmltYXJ5LndpZHRoO1xuICAgICAgICB0aGlzLl9wcmltYXJ5QXJlYUhlaWdodCA9IHRoaXMuX2NvbmZpZ1ByaW1hcnkuaGVpZ2h0O1xuICAgICAgICBpZiAoX2NvbmZpZy5hcmVhV2lkdGggJiYgX2NvbmZpZy5hcmVhSGVpZ2h0KSB7XG4gICAgICAgICAgICB0aGlzLmNvbmZpZy53aWR0aCA9IF9jb25maWcuYXJlYVdpZHRoO1xuICAgICAgICAgICAgdGhpcy5jb25maWcuaGVpZ2h0ID0gX2NvbmZpZy5hcmVhSGVpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIHNyYyA9IG5vcm1hbGl6ZVNWRyhzcmMpO1xuXG4gICAgICAgIGNvbnN0IGltZyA9IGNyZWF0ZUh0bWxJbWcoc3JjKTtcblxuICAgICAgICBjb25zdCBjcm9wRXZlbnQgPSB7IC4uLl9jb25maWcgfSBhcyBJbWdDcm9wcGVyRXZlbnQ7XG5cbiAgICAgICAgbmV3IE9ic2VydmFibGU8dm9pZD4ob2JzZXJ2ZXIgPT4ge1xuXG4gICAgICAgICAgICBpbWcub25lcnJvciA9IGVyciA9PiBvYnNlcnZlci5lcnJvcihlcnIpO1xuICAgICAgICAgICAgaW1nLm9uYWJvcnQgPSBlcnIgPT4gb2JzZXJ2ZXIuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgIGltZy5vbmxvYWQgPSAoKSA9PiBvYnNlcnZlci5uZXh0KG51bGwpO1xuICAgICAgICB9KVxuICAgICAgICAgICAgLnBpcGUodGFrZSgxKSwgdGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3kpKVxuICAgICAgICAgICAgLnN1YnNjcmliZShcbiAgICAgICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2ltZ0xvYWRlZChpbWcpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9pc0xvYWRlZEltZyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW1hZ2VMb2FkZWQuZW1pdChjcm9wRXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNkLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmdab25lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLm9uU3RhYmxlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFzT2JzZXJ2YWJsZSgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnBpcGUodGFrZSgxKSwgdGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3kpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgpID0+IHNldFRpbWVvdXQoKCkgPT4gdGhpcy5fbmdab25lLnJ1bigoKSA9PiB0aGlzLl9wb3NpdGlvbkltZyhjcm9wRXZlbnQsIGZuKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yOiBJbWdDcm9wcGVyRXJyb3JFdmVudCA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IF9jb25maWcubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yOiBJbWdDcm9wcGVyRXJyb3IuVHlwZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IF9jb25maWcudHlwZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpemU6IF9jb25maWcuc2l6ZVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9yLmVtaXQoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfdXBkYXRlQXJlYUlmTmVlZGVkKCkge1xuICAgICAgICBpZiAoIXRoaXMuX2NvbmZpZy5yZXNwb25zaXZlQXJlYSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgcm9vdFJlY3QgPSB0aGlzLl9yb290UmVjdCgpO1xuICAgICAgICBjb25zdCBhcmVhUmVjdCA9IHRoaXMuX2FyZWFDcm9wcGVyUmVjdCgpO1xuICAgICAgICBjb25zdCBtaW5XaWR0aCA9IHRoaXMuY29uZmlnLm1pbldpZHRoIHx8IDE7XG4gICAgICAgIGNvbnN0IG1pbkhlaWdodCA9IHRoaXMuY29uZmlnLm1pbkhlaWdodCB8fCAxO1xuICAgICAgICBpZiAoIShcbiAgICAgICAgICAgIGFyZWFSZWN0LndpZHRoID4gcm9vdFJlY3Qud2lkdGhcbiAgICAgICAgICAgIHx8IGFyZWFSZWN0LmhlaWdodCA+IHJvb3RSZWN0LmhlaWdodFxuICAgICAgICAgICAgfHwgYXJlYVJlY3Qud2lkdGggPCB0aGlzLl9wcmltYXJ5QXJlYVdpZHRoXG4gICAgICAgICAgICB8fCBhcmVhUmVjdC5oZWlnaHQgPCB0aGlzLl9wcmltYXJ5QXJlYUhlaWdodFxuICAgICAgICApKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXJlYVdpZHRoQ29uZiA9IE1hdGgubWF4KHRoaXMuY29uZmlnLndpZHRoLCBtaW5XaWR0aCk7XG4gICAgICAgIGNvbnN0IGFyZWFXaWR0aE1heCA9IE1hdGgubWF4KHJvb3RSZWN0LndpZHRoLCBtaW5XaWR0aCk7XG4gICAgICAgIGNvbnN0IG1pbkhvc3QgPSBNYXRoLm1pbihcbiAgICAgICAgICAgIE1hdGgubWF4KHJvb3RSZWN0LndpZHRoLCBtaW5XaWR0aCksIE1hdGgubWF4KHJvb3RSZWN0LmhlaWdodCwgbWluSGVpZ2h0KVxuICAgICAgICApO1xuICAgICAgICBjb25zdCBjdXJyZW50U2NhbGUgPSB0aGlzLl9zY2FsM0ZpeDtcbiAgICAgICAgbGV0IG5ld1NjYWxlID0gMDtcbiAgICAgICAgY29uc3Qgcm91bmRDb25mID0gdGhpcy5jb25maWcucm91bmQ7XG5cbiAgICAgICAgaWYgKHJvdW5kQ29uZikge1xuICAgICAgICAgICAgdGhpcy5jb25maWcud2lkdGggPSB0aGlzLmNvbmZpZy5oZWlnaHQgPSBtaW5Ib3N0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGFyZWFXaWR0aENvbmYgPT09IGFyZWFSZWN0LndpZHRoKSB7XG4gICAgICAgICAgICAgICAgaWYgKGFyZWFXaWR0aE1heCA+IHRoaXMuX3ByaW1hcnlBcmVhV2lkdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWcud2lkdGggPSB0aGlzLl9wcmltYXJ5QXJlYVdpZHRoO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy5oZWlnaHQgPSAodGhpcy5fcHJpbWFyeUFyZWFXaWR0aCAqIGFyZWFSZWN0LmhlaWdodCkgLyBhcmVhUmVjdC53aWR0aDtcbiAgICAgICAgICAgICAgICAgICAgbmV3U2NhbGUgPSAoY3VycmVudFNjYWxlICogdGhpcy5fcHJpbWFyeUFyZWFXaWR0aCkgLyBhcmVhUmVjdC53aWR0aDtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy53aWR0aCA9IGFyZWFXaWR0aE1heDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWcuaGVpZ2h0ID0gKGFyZWFXaWR0aE1heCAqIGFyZWFSZWN0LmhlaWdodCkgLyBhcmVhUmVjdC53aWR0aDtcbiAgICAgICAgICAgICAgICAgICAgbmV3U2NhbGUgPSAoY3VycmVudFNjYWxlICogYXJlYVdpZHRoTWF4KSAvIGFyZWFSZWN0LndpZHRoO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLl91cGRhdGVNaW5TY2FsZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3VwZGF0ZU1heFNjYWxlKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTY2FsZShuZXdTY2FsZSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fbWFya0ZvckNoZWNrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIF91cGRhdGVBYnNvbHV0ZVNjYWxlKCkge1xuICAgICAgICBjb25zdCBzY2FsZSA9IHRoaXMuX3NjYWwzRml4IC8gKHRoaXMuY29uZmlnLndpZHRoIC8gdGhpcy5fcHJpbWFyeUFyZWFXaWR0aCk7XG4gICAgICAgIHRoaXMuX2Fic29sdXRlU2NhbGUgPSBzY2FsZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMb2FkIEltYWdlIGZyb20gVVJMXG4gICAgICogQGRlcHJlY2F0ZWQgVXNlIGBsb2FkSW1hZ2VgIGluc3RlYWQgb2YgYHNldEltYWdlVXJsYFxuICAgICAqIEBwYXJhbSBzcmMgVVJMXG4gICAgICogQHBhcmFtIGZuIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBjYWxsZWQgYmVmb3JlIGVtaXQgdGhlIGV2ZW50IGxvYWRlZFxuICAgICAqL1xuICAgIHB1YmxpYyBzZXRJbWFnZVVybChzcmM6IHN0cmluZywgZm4/OiAoKSA9PiB2b2lkKSB7XG4gICAgICAgIHRoaXMubG9hZEltYWdlKHNyYywgZm4pO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3Bvc2l0aW9uSW1nKGNyb3BFdmVudDogSW1nQ3JvcHBlckV2ZW50LCBmbj86ICgpID0+IHZvaWQpIHtcbiAgICAgICAgY29uc3QgbG9hZENvbmZpZyA9IHRoaXMuX2N1cnJlbnRMb2FkQ29uZmlnO1xuICAgICAgICB0aGlzLl91cGRhdGVNaW5TY2FsZSh0aGlzLl9pbWdDYW52YXMubmF0aXZlRWxlbWVudCk7XG4gICAgICAgIHRoaXMuX3VwZGF0ZU1heFNjYWxlKCk7XG4gICAgICAgIHRoaXMuaXNMb2FkZWQgPSBmYWxzZTtcbiAgICAgICAgaWYgKGZuKSB7XG4gICAgICAgICAgICBmbigpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGxvYWRDb25maWcuc2NhbGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFNjYWxlKGxvYWRDb25maWcuc2NhbGUsIHRydWUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFNjYWxlKHRoaXMubWluU2NhbGUsIHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5yb3RhdGUobG9hZENvbmZpZy5yb3RhdGlvbiB8fCAwKTtcbiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUFyZWFJZk5lZWRlZCgpO1xuICAgICAgICAgICAgdGhpcy5fbWFya0ZvckNoZWNrKCk7XG4gICAgICAgICAgICB0aGlzLl9uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX25nWm9uZVxuICAgICAgICAgICAgICAgICAgICAub25TdGFibGVcbiAgICAgICAgICAgICAgICAgICAgLmFzT2JzZXJ2YWJsZSgpXG4gICAgICAgICAgICAgICAgICAgIC5waXBlKHRha2UoMSksIHRha2VVbnRpbCh0aGlzLl9kZXN0cm95KSlcbiAgICAgICAgICAgICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobG9hZENvbmZpZy54T3JpZ2luICE9IG51bGwgJiYgbG9hZENvbmZpZy55T3JpZ2luICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVBvc2l0aW9uKGxvYWRDb25maWcueE9yaWdpbiwgbG9hZENvbmZpZy55T3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUFyZWFJZk5lZWRlZCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0xvYWRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9jcm9wSWZBdXRvQ3JvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWFya0ZvckNoZWNrKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWFkeS5lbWl0KGNyb3BFdmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyByb3RhdGUoZGVncmVlczogbnVtYmVyKSB7XG4gICAgICAgIGxldCB2YWxpZERlZ3JlZXMgPSBfbm9ybWFsaXplRGVncmVlcyhkZWdyZWVzKTtcbiAgICAgICAgLy8gSWYgbmVnYXRpdmUgY29udmVydCB0byBwb3NpdGl2ZVxuICAgICAgICBpZiAodmFsaWREZWdyZWVzIDwgMCkge1xuICAgICAgICAgICAgdmFsaWREZWdyZWVzICs9IDM2MDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuZXdSb3RhdGlvbiA9IF9ub3JtYWxpemVEZWdyZWVzKCh0aGlzLl9yb3RhdGlvbiB8fCAwKSArIHZhbGlkRGVncmVlcyk7XG4gICAgICAgIGlmIChuZXdSb3RhdGlvbiA9PT0gdGhpcy5fcm90YXRpb24pIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkZWdyZWVzUmFkID0gdmFsaWREZWdyZWVzICogTWF0aC5QSSAvIDE4MDtcbiAgICAgICAgY29uc3QgY2FudmFzID0gdGhpcy5faW1nQ2FudmFzLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgIGNvbnN0IGNhbnZhc0Nsb24gPSBjcmVhdGVDYW52YXNJbWcoY2FudmFzKTtcbiAgICAgICAgY29uc3QgY3R4ID0gY2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcbiAgICAgICAgdGhpcy5fcm90YXRpb24gPSBuZXdSb3RhdGlvbjtcblxuICAgICAgICAvLyBjbGVhclxuICAgICAgICBjdHguY2xlYXJSZWN0KDAsIDAsIGNhbnZhc0Nsb24ud2lkdGgsIGNhbnZhc0Nsb24uaGVpZ2h0KTtcblxuICAgICAgICAvLyByb3RhdGUgY2FudmFzIGltYWdlXG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IGByb3RhdGUoJHt2YWxpZERlZ3JlZXN9ZGVnKSBzY2FsZSgkezEgLyB0aGlzLl9zY2FsM0ZpeH0pYDtcbiAgICAgICAgY29uc3QgdHJhbnNmb3JtT3JpZ2luID0gYCR7dGhpcy5faW1nUmVjdC54Y31weCAke3RoaXMuX2ltZ1JlY3QueWN9cHggMGA7XG4gICAgICAgIGNhbnZhcy5zdHlsZS50cmFuc2Zvcm0gPSB0cmFuc2Zvcm07XG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogZGVwcmVjYXRpb25cbiAgICAgICAgY2FudmFzLnN0eWxlLndlYmtpdFRyYW5zZm9ybSA9IHRyYW5zZm9ybTtcbiAgICAgICAgY2FudmFzLnN0eWxlLnRyYW5zZm9ybU9yaWdpbiA9IHRyYW5zZm9ybU9yaWdpbjtcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOiBkZXByZWNhdGlvblxuICAgICAgICBjYW52YXMuc3R5bGUud2Via2l0VHJhbnNmb3JtT3JpZ2luID0gdHJhbnNmb3JtT3JpZ2luO1xuXG4gICAgICAgIGNvbnN0IHsgbGVmdCwgdG9wIH0gPSBjYW52YXMuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkgYXMgRE9NUmVjdDtcblxuICAgICAgICAvLyBzYXZlIHJlY3RcbiAgICAgICAgY29uc3QgY2FudmFzUmVjdCA9IGNhbnZhcy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgICAgICAvLyByZW1vdmUgcm90YXRlIHN0eWxlc1xuICAgICAgICBjYW52YXMucmVtb3ZlQXR0cmlidXRlKFwic3R5bGVcIik7XG5cbiAgICAgICAgLy8gc2V0IHcgJiBoXG4gICAgICAgIGNvbnN0IHcgPSBjYW52YXNSZWN0LndpZHRoO1xuICAgICAgICBjb25zdCBoID0gY2FudmFzUmVjdC5oZWlnaHQ7XG4gICAgICAgIGN0eC5jYW52YXMud2lkdGggPSB3O1xuICAgICAgICBjdHguY2FudmFzLmhlaWdodCA9IGg7XG5cbiAgICAgICAgLy8gY2xlYXJcbiAgICAgICAgY3R4LmNsZWFyUmVjdCgwLCAwLCB3LCBoKTtcblxuICAgICAgICAvLyB0cmFuc2xhdGUgYW5kIHJvdGF0ZVxuICAgICAgICBjdHgudHJhbnNsYXRlKHcgLyAyLCBoIC8gMik7XG4gICAgICAgIGN0eC5yb3RhdGUoZGVncmVlc1JhZCk7XG4gICAgICAgIGN0eC5kcmF3SW1hZ2UoY2FudmFzQ2xvbiwgLWNhbnZhc0Nsb24ud2lkdGggLyAyLCAtY2FudmFzQ2xvbi5oZWlnaHQgLyAyKTtcblxuICAgICAgICAvLyBVcGRhdGUgbWluIHNjYWxlXG4gICAgICAgIHRoaXMuX3VwZGF0ZU1pblNjYWxlKGNhbnZhcyk7XG4gICAgICAgIHRoaXMuX3VwZGF0ZU1heFNjYWxlKCk7XG5cbiAgICAgICAgLy8gc2V0IHRoZSBtaW5pbXVtIHNjYWxlLCBvbmx5IGlmIG5lY2Vzc2FyeVxuICAgICAgICBpZiAodGhpcy5zY2FsZSA8IHRoaXMubWluU2NhbGUpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U2NhbGUoMCwgdHJ1ZSk7XG4gICAgICAgIH0gLy8gICAgICAgICAgICAgICAg4oaRIG5vIEF1dG9Dcm9wXG5cbiAgICAgICAgY29uc3Qgcm9vdFJlY3QgPSB0aGlzLl9yb290UmVjdCgpO1xuXG4gICAgICAgIHRoaXMuX3NldFN0eWxlc0ZvckNvbnRJbWcoe1xuICAgICAgICAgICAgeDogKGxlZnQgLSByb290UmVjdC5sZWZ0KSxcbiAgICAgICAgICAgIHk6ICh0b3AgLSByb290UmVjdC50b3ApXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIGtlZXAgaW1hZ2UgaW5zaWRlIHRoZSBmcmFtZVxuICAgICAgICBjb25zdCBvcmlnaW5Qb3NpdGlvbiA9IHsuLi50aGlzLl9pbWdSZWN0fTtcbiAgICAgICAgdGhpcy5vZmZzZXQgPSB7XG4gICAgICAgICAgICB4OiBvcmlnaW5Qb3NpdGlvbi54LFxuICAgICAgICAgICAgeTogb3JpZ2luUG9zaXRpb24ueSxcbiAgICAgICAgICAgIGxlZnQ6IG9yaWdpblBvc2l0aW9uLnhjLFxuICAgICAgICAgICAgdG9wOiBvcmlnaW5Qb3NpdGlvbi55Y1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLl9zZXRTdHlsZXNGb3JDb250SW1nKHt9KTtcbiAgICAgICAgdGhpcy5fc2ltdWxhdGVQb2ludGVyTW92ZSgpO1xuXG4gICAgICAgIHRoaXMuX2Nyb3BJZkF1dG9Dcm9wKCk7XG4gICAgfVxuXG4gICAgcHVibGljIF91cGRhdGVNaW5TY2FsZShjYW52YXM/OiBIVE1MQ2FudmFzRWxlbWVudCkge1xuICAgICAgICBpZiAoIWNhbnZhcykge1xuICAgICAgICAgICAgY2FudmFzID0gdGhpcy5faW1nQ2FudmFzLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY29uZmlnID0gdGhpcy5jb25maWc7XG4gICAgICAgIGNvbnN0IG1pblNjYWxlID0gKGNvbmZpZy5leHRyYVpvb21PdXQgPyBNYXRoLm1pbiA6IE1hdGgubWF4KShcbiAgICAgICAgICAgIGNvbmZpZy53aWR0aCAvIGNhbnZhcy53aWR0aCxcbiAgICAgICAgICAgIGNvbmZpZy5oZWlnaHQgLyBjYW52YXMuaGVpZ2h0KTtcbiAgICAgICAgdGhpcy5fbWluU2NhbGUgPSBtaW5TY2FsZTtcbiAgICAgICAgdGhpcy5taW5TY2FsZUNoYW5nZS5lbWl0KG1pblNjYWxlKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF91cGRhdGVNYXhTY2FsZSgpIHtcbiAgICAgICAgY29uc3QgbWF4U2NhbGUgPSAodGhpcy5jb25maWcud2lkdGggLyB0aGlzLl9wcmltYXJ5QXJlYVdpZHRoKTtcbiAgICAgICAgdGhpcy5fbWF4U2NhbGUgPSBtYXhTY2FsZTtcbiAgICAgICAgdGhpcy5tYXhTY2FsZUNoYW5nZS5lbWl0KG1heFNjYWxlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXNpemUgJiBjcm9wIGltYWdlXG4gICAgICovXG4gICAgcHVibGljIGNyb3AoY29uZmlnPzogSW1nQ3JvcHBlckNvbmZpZyk6IEltZ0Nyb3BwZXJFdmVudCB7XG4gICAgICAgIGNvbnN0IG5ld0NvbmZpZyA9IGNvbmZpZ1xuICAgICAgICAgICAgPyBtZXJnZURlZXAoeyB9LCB0aGlzLmNvbmZpZyB8fCBuZXcgSW1nQ3JvcHBlckNvbmZpZygpLCBjb25maWcpIDogdGhpcy5jb25maWc7XG4gICAgICAgIGNvbnN0IGNyb3BFdmVudCA9IHRoaXMuX2ltZ0Nyb3AobmV3Q29uZmlnKTtcbiAgICAgICAgdGhpcy5jZC5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgcmV0dXJuIGNyb3BFdmVudDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAZG9jcy1wcml2YXRlXG4gICAgICovXG4gICAgcHJpdmF0ZSBfaW1nQ3JvcChteUNvbmZpZzogSW1nQ3JvcHBlckNvbmZpZykge1xuICAgICAgICBjb25zdCBjYW52YXNFbGVtZW50OiBIVE1MQ2FudmFzRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIik7XG4gICAgICAgIGNvbnN0IGFyZWFSZWN0ID0gdGhpcy5fYXJlYUNyb3BwZXJSZWN0KCk7XG4gICAgICAgIGNvbnN0IGNhbnZhc1JlY3QgPSB0aGlzLl9jYW52YXNSZWN0KCk7XG4gICAgICAgIGNvbnN0IHNjYWxlRml4ID0gdGhpcy5fc2NhbDNGaXg7XG4gICAgICAgIGNvbnN0IGxlZnQgPSAoYXJlYVJlY3QubGVmdCAtIGNhbnZhc1JlY3QubGVmdCkgLyBzY2FsZUZpeDtcbiAgICAgICAgY29uc3QgdG9wID0gKGFyZWFSZWN0LnRvcCAtIGNhbnZhc1JlY3QudG9wKSAvIHNjYWxlRml4O1xuICAgICAgICBjb25zdCB7IG91dHB1dCB9ID0gbXlDb25maWc7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRJbWFnZUxvYWRDb25maWcgPSB0aGlzLl9jdXJyZW50TG9hZENvbmZpZztcbiAgICAgICAgY29uc3QgYXJlYSA9IHtcbiAgICAgICAgICAgIHdpZHRoOiBteUNvbmZpZy53aWR0aCxcbiAgICAgICAgICAgIGhlaWdodDogbXlDb25maWcuaGVpZ2h0XG4gICAgICAgIH07XG4gICAgICAgIGNhbnZhc0VsZW1lbnQud2lkdGggPSBhcmVhLndpZHRoIC8gc2NhbGVGaXg7XG4gICAgICAgIGNhbnZhc0VsZW1lbnQuaGVpZ2h0ID0gYXJlYS5oZWlnaHQgLyBzY2FsZUZpeDtcbiAgICAgICAgY29uc3QgY3R4ID0gY2FudmFzRWxlbWVudC5nZXRDb250ZXh0KFwiMmRcIik7XG4gICAgICAgIGlmIChteUNvbmZpZy5maWxsKSB7XG4gICAgICAgICAgICBjdHguZmlsbFN0eWxlID0gbXlDb25maWcuZmlsbDtcbiAgICAgICAgICAgIGN0eC5maWxsUmVjdCgwLCAwLCBjYW52YXNFbGVtZW50LndpZHRoLCBjYW52YXNFbGVtZW50LmhlaWdodCk7XG4gICAgICAgIH1cbiAgICAgICAgY3R4LmRyYXdJbWFnZSh0aGlzLl9pbWdDYW52YXMubmF0aXZlRWxlbWVudCxcbiAgICAgICAgICAgIC0obGVmdCksIC0odG9wKSxcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gY2FudmFzRWxlbWVudDtcbiAgICAgICAgaWYgKG15Q29uZmlnLm91dHB1dCA9PT0gSW1nUmVzb2x1dGlvbi5EZWZhdWx0KSB7XG4gICAgICAgICAgICByZXNpemVDYW52YXMoXG4gICAgICAgICAgICAgICAgcmVzdWx0LFxuICAgICAgICAgICAgICAgIHRoaXMuX2NvbmZpZ1ByaW1hcnkud2lkdGgsXG4gICAgICAgICAgICAgICAgdGhpcy5fY29uZmlnUHJpbWFyeS5oZWlnaHQpO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBvdXRwdXQgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgIGlmIChvdXRwdXQud2lkdGggJiYgb3V0cHV0LmhlaWdodCkge1xuICAgICAgICAgICAgICAgIHJlc2l6ZUNhbnZhcyhyZXN1bHQsIG91dHB1dC53aWR0aCwgb3V0cHV0LmhlaWdodCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG91dHB1dC53aWR0aCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld0hlaWdodCA9IGFyZWEuaGVpZ2h0ICogb3V0cHV0LndpZHRoIC8gYXJlYS53aWR0aDtcbiAgICAgICAgICAgICAgICByZXNpemVDYW52YXMocmVzdWx0LCBvdXRwdXQud2lkdGgsIG5ld0hlaWdodCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG91dHB1dC5oZWlnaHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdXaWR0aCA9IGFyZWEud2lkdGggKiBvdXRwdXQuaGVpZ2h0IC8gYXJlYS5oZWlnaHQ7XG4gICAgICAgICAgICAgICAgcmVzaXplQ2FudmFzKHJlc3VsdCwgbmV3V2lkdGgsIG91dHB1dC5oZWlnaHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHR5cGUgPSBjdXJyZW50SW1hZ2VMb2FkQ29uZmlnLm9yaWdpbmFsRGF0YVVSTC5zdGFydHNXaXRoKFwiaHR0cFwiKVxuICAgICAgICAgICAgPyBjdXJyZW50SW1hZ2VMb2FkQ29uZmlnLnR5cGUgfHwgbXlDb25maWcudHlwZVxuICAgICAgICAgICAgOiBteUNvbmZpZy50eXBlIHx8IGN1cnJlbnRJbWFnZUxvYWRDb25maWcudHlwZTtcbiAgICAgICAgY29uc3QgZGF0YVVSTCA9IHJlc3VsdC50b0RhdGFVUkwodHlwZSk7XG4gICAgICAgIGNvbnN0IGNyb3BFdmVudDogSW1nQ3JvcHBlckV2ZW50ID0ge1xuICAgICAgICAgICAgZGF0YVVSTCxcbiAgICAgICAgICAgIHR5cGUsXG4gICAgICAgICAgICBuYW1lOiBjdXJyZW50SW1hZ2VMb2FkQ29uZmlnLm5hbWUsXG4gICAgICAgICAgICBhcmVhV2lkdGg6IHRoaXMuX3ByaW1hcnlBcmVhV2lkdGgsXG4gICAgICAgICAgICBhcmVhSGVpZ2h0OiB0aGlzLl9wcmltYXJ5QXJlYUhlaWdodCxcbiAgICAgICAgICAgIHdpZHRoOiByZXN1bHQud2lkdGgsXG4gICAgICAgICAgICBoZWlnaHQ6IHJlc3VsdC5oZWlnaHQsXG4gICAgICAgICAgICBvcmlnaW5hbERhdGFVUkw6IGN1cnJlbnRJbWFnZUxvYWRDb25maWcub3JpZ2luYWxEYXRhVVJMLFxuICAgICAgICAgICAgc2NhbGU6IHRoaXMuX2Fic29sdXRlU2NhbGUsXG4gICAgICAgICAgICByb3RhdGlvbjogdGhpcy5fcm90YXRpb24sXG4gICAgICAgICAgICBsZWZ0OiAoYXJlYVJlY3QubGVmdCAtIGNhbnZhc1JlY3QubGVmdCkgLyB0aGlzLl9zY2FsM0ZpeCxcbiAgICAgICAgICAgIHRvcDogKGFyZWFSZWN0LnRvcCAtIGNhbnZhc1JlY3QudG9wKSAvIHRoaXMuX3NjYWwzRml4LFxuICAgICAgICAgICAgc2l6ZTogY3VycmVudEltYWdlTG9hZENvbmZpZy5zaXplLFxuICAgICAgICAgICAgeE9yaWdpbjogdGhpcy5faW1nUmVjdC54YyxcbiAgICAgICAgICAgIHlPcmlnaW46IHRoaXMuX2ltZ1JlY3QueWMsXG4gICAgICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgICAgICAgIHg6IHRoaXMuX2ltZ1JlY3QueGMsXG4gICAgICAgICAgICAgICAgeTogdGhpcy5faW1nUmVjdC55Y1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuaXNDcm9wcGVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5jcm9wcGVkLmVtaXQoY3JvcEV2ZW50KTtcbiAgICAgICAgcmV0dXJuIGNyb3BFdmVudDtcbiAgICB9XG5cbiAgICBwdWJsaWMgX3Jvb3RSZWN0KCk6IERPTVJlY3Qge1xuICAgICAgICByZXR1cm4gdGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpIGFzIERPTVJlY3Q7XG4gICAgfVxuXG4gICAgcHVibGljIF9hcmVhQ3JvcHBlclJlY3QoKTogRE9NUmVjdCB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hcmVhUmVmLm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkgYXMgRE9NUmVjdDtcbiAgICB9XG5cbiAgICBwdWJsaWMgX2NhbnZhc1JlY3QoKTogRE9NUmVjdCB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pbWdDYW52YXMubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICB9XG5cblxuICAgIC8qKiBDYWxsZWQgd2hlbiB0aGUgdXNlciBoYXMgbGlmdGVkIHRoZWlyIHBvaW50ZXIuICovXG4gICAgcHJpdmF0ZSBfcG9pbnRlclVwID0gKGV2ZW50OiBUb3VjaEV2ZW50IHwgTW91c2VFdmVudCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5faXNTbGlkaW5nKSB7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgdGhpcy5fcmVtb3ZlR2xvYmFsRXZlbnRzKCk7XG4gICAgICAgICAgICB0aGlzLl9pc1NsaWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0UG9pbnRlckV2ZW50ID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX2Nyb3BJZkF1dG9Dcm9wKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQ2FsbGVkIHdoZW4gdGhlIHdpbmRvdyBoYXMgbG9zdCBmb2N1cy4gKi9cbiAgICBwcml2YXRlIF93aW5kb3dCbHVyID0gKCkgPT4ge1xuICAgICAgICAvLyBJZiB0aGUgd2luZG93IGlzIGJsdXJyZWQgd2hpbGUgZHJhZ2dpbmcgd2UgbmVlZCB0byBzdG9wIGRyYWdnaW5nIGJlY2F1c2UgdGhlXG4gICAgICAgIC8vIGJyb3dzZXIgd29uJ3QgZGlzcGF0Y2ggdGhlIGBtb3VzZXVwYCBhbmQgYHRvdWNoZW5kYCBldmVudHMgYW55bW9yZS5cbiAgICAgICAgaWYgKHRoaXMuX2xhc3RQb2ludGVyRXZlbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX3BvaW50ZXJVcCh0aGlzLl9sYXN0UG9pbnRlckV2ZW50KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgX2JpbmRHbG9iYWxFdmVudHModHJpZ2dlckV2ZW50OiBUb3VjaEV2ZW50IHwgTW91c2VFdmVudCkge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5fZG9jdW1lbnQ7XG4gICAgICAgIGNvbnN0IGlzVG91Y2ggPSBpc1RvdWNoRXZlbnQodHJpZ2dlckV2ZW50KTtcbiAgICAgICAgY29uc3QgbW92ZUV2ZW50TmFtZSA9IGlzVG91Y2ggPyBcInRvdWNobW92ZVwiIDogXCJtb3VzZW1vdmVcIjtcbiAgICAgICAgY29uc3QgZW5kRXZlbnROYW1lID0gaXNUb3VjaCA/IFwidG91Y2hlbmRcIiA6IFwibW91c2V1cFwiO1xuICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIobW92ZUV2ZW50TmFtZSwgdGhpcy5fcG9pbnRlck1vdmUsIGFjdGl2ZUV2ZW50T3B0aW9ucyk7XG4gICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihlbmRFdmVudE5hbWUsIHRoaXMuX3BvaW50ZXJVcCwgYWN0aXZlRXZlbnRPcHRpb25zKTtcblxuICAgICAgICBpZiAoaXNUb3VjaCkge1xuICAgICAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hjYW5jZWxcIiwgdGhpcy5fcG9pbnRlclVwLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgd2luZG93ID0gdGhpcy5fZ2V0V2luZG93KCk7XG5cbiAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgJiYgd2luZG93KSB7XG4gICAgICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcImJsdXJcIiwgdGhpcy5fd2luZG93Qmx1cik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogUmVtb3ZlcyBhbnkgZ2xvYmFsIGV2ZW50IGxpc3RlbmVycyB0aGF0IHdlIG1heSBoYXZlIGFkZGVkLiAqL1xuICAgIHByaXZhdGUgX3JlbW92ZUdsb2JhbEV2ZW50cygpIHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuX2RvY3VtZW50O1xuICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtb3VzZW1vdmVcIiwgdGhpcy5fcG9pbnRlck1vdmUsIGFjdGl2ZUV2ZW50T3B0aW9ucyk7XG4gICAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1vdXNldXBcIiwgdGhpcy5fcG9pbnRlclVwLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ0b3VjaG1vdmVcIiwgdGhpcy5fcG9pbnRlck1vdmUsIGFjdGl2ZUV2ZW50T3B0aW9ucyk7XG4gICAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRvdWNoZW5kXCIsIHRoaXMuX3BvaW50ZXJVcCwgYWN0aXZlRXZlbnRPcHRpb25zKTtcbiAgICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2hjYW5jZWxcIiwgdGhpcy5fcG9pbnRlclVwLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuXG4gICAgICAgIGNvbnN0IHdpbmRvdyA9IHRoaXMuX2dldFdpbmRvdygpO1xuXG4gICAgICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiICYmIHdpbmRvdykge1xuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJibHVyXCIsIHRoaXMuX3dpbmRvd0JsdXIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIFVzZSBkZWZhdWx0VmlldyBvZiBpbmplY3RlZCBkb2N1bWVudCBpZiBhdmFpbGFibGUgb3IgZmFsbGJhY2sgdG8gZ2xvYmFsIHdpbmRvdyByZWZlcmVuY2UgKi9cbiAgICBwcml2YXRlIF9nZXRXaW5kb3coKTogV2luZG93IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RvY3VtZW50LmRlZmF1bHRWaWV3IHx8IHdpbmRvdztcbiAgICB9XG5cbn1cblxuLyoqXG4gKiBOb3JtYWxpemUgZGVncmVlcyBmb3IgY3JvcHBlciByb3RhdGlvblxuICogQGRvY3MtcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX25vcm1hbGl6ZURlZ3JlZXMobjogbnVtYmVyKSB7XG4gICAgY29uc3QgZGUgPSBuICUgMzYwO1xuICAgIGlmIChkZSAlIDkwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTHlDcm9wcGVyOiBJbnZhbGlkIFxcYCR7bn1cXGAgZGVncmVlLCBvbmx5IGFjY2VwdGVkIHZhbHVlczogMCwgOTAsIDE4MCwgMjcwICYgMzYwLmApO1xuICAgIH1cbiAgICByZXR1cm4gZGU7XG59XG5cbi8qKlxuICogQGRvY3MtcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBjcmVhdGVDYW52YXNJbWcoaW1nOiBIVE1MQ2FudmFzRWxlbWVudCB8IEhUTUxJbWFnZUVsZW1lbnQpIHtcblxuICAgIC8vIGNyZWF0ZSBhIG5ldyBjYW52YXNcbiAgICBjb25zdCBuZXdDYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiY2FudmFzXCIpO1xuICAgIGNvbnN0IGNvbnRleHQgPSBuZXdDYW52YXMuZ2V0Q29udGV4dChcIjJkXCIpO1xuXG4gICAgLy8gc2V0IGRpbWVuc2lvbnNcbiAgICBuZXdDYW52YXMud2lkdGggPSBpbWcud2lkdGg7XG4gICAgbmV3Q2FudmFzLmhlaWdodCA9IGltZy5oZWlnaHQ7XG5cbiAgICAvLyBhcHBseSB0aGUgb2xkIGNhbnZhcyB0byB0aGUgbmV3IG9uZVxuICAgIGNvbnRleHQuZHJhd0ltYWdlKGltZywgMCwgMCk7XG5cbiAgICAvLyByZXR1cm4gdGhlIG5ldyBjYW52YXNcbiAgICByZXR1cm4gbmV3Q2FudmFzO1xufVxuXG5cbmNvbnN0IERBVEFfSU1BR0VfU1ZHX1BSRUZJWCA9IFwiZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxcIjtcblxuZnVuY3Rpb24gbm9ybWFsaXplU1ZHKGRhdGFVUkw6IHN0cmluZykge1xuICAgIGlmICh3aW5kb3cuYXRvYiAmJiBpc1N2Z0ltYWdlKGRhdGFVUkwpKSB7XG4gICAgICAgIGNvbnN0IGxlbiA9IGRhdGFVUkwubGVuZ3RoIC8gNTtcbiAgICAgICAgY29uc3QgdGV4dCA9IHdpbmRvdy5hdG9iKGRhdGFVUkwucmVwbGFjZShEQVRBX0lNQUdFX1NWR19QUkVGSVgsIFwiXCIpKTtcbiAgICAgICAgY29uc3Qgc3BhbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIpO1xuICAgICAgICBzcGFuLmlubmVySFRNTCA9IHRleHQ7XG4gICAgICAgIGNvbnN0IHN2ZyA9IHNwYW4ucXVlcnlTZWxlY3RvcihcInN2Z1wiKTtcbiAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGUoXCJzdHlsZVwiLCBcImRpc3BsYXk6bm9uZVwiKTtcbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChzcGFuKTtcbiAgICAgICAgY29uc3Qgd2lkdGggPSBwYXJzZUZsb2F0KGdldENvbXB1dGVkU3R5bGUoc3ZnKS53aWR0aCkgfHwgMTtcbiAgICAgICAgY29uc3QgaGVpZ2h0ID0gcGFyc2VGbG9hdChnZXRDb21wdXRlZFN0eWxlKHN2ZykuaGVpZ2h0KSB8fCAxO1xuICAgICAgICBjb25zdCBtYXggPSBNYXRoLm1heCh3aWR0aCwgaGVpZ2h0KTtcblxuICAgICAgICBzdmcuc2V0QXR0cmlidXRlKFwid2lkdGhcIiwgYCR7bGVuIC8gKHdpZHRoIC8gbWF4KX1weGApO1xuICAgICAgICBzdmcuc2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIsIGAke2xlbiAvIChoZWlnaHQgLyBtYXgpfXB4YCk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IERBVEFfSU1BR0VfU1ZHX1BSRUZJWCArIHdpbmRvdy5idG9hKHNwYW4uaW5uZXJIVE1MKTtcbiAgICAgICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChzcGFuKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgcmV0dXJuIGRhdGFVUkw7XG59XG5cbmZ1bmN0aW9uIGlzU3ZnSW1hZ2UoZGF0YVVybDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGRhdGFVcmwuc3RhcnRzV2l0aChEQVRBX0lNQUdFX1NWR19QUkVGSVgpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVIdG1sSW1nKHNyYzogc3RyaW5nKSB7XG4gICAgY29uc3QgaW1nID0gbmV3IEltYWdlKCk7XG4gICAgaW1nLmNyb3NzT3JpZ2luID0gXCJhbm9ueW1vdXNcIjtcbiAgICBpbWcuc3JjID0gc3JjO1xuICAgIHJldHVybiBpbWc7XG59XG5cblxuZnVuY3Rpb24gZ2V0R2VzdHVyZVBvaW50RnJvbUV2ZW50KGV2ZW50OiBUb3VjaEV2ZW50IHwgTW91c2VFdmVudCkge1xuXG4gICAgLy8gYHRvdWNoZXNgIHdpbGwgYmUgZW1wdHkgZm9yIHN0YXJ0L2VuZCBldmVudHMgc28gd2UgaGF2ZSB0byBmYWxsIGJhY2sgdG8gYGNoYW5nZWRUb3VjaGVzYC5cbiAgICBjb25zdCBwb2ludCA9IGlzVG91Y2hFdmVudChldmVudClcbiAgICAgICAgPyAoZXZlbnQudG91Y2hlc1swXSB8fCBldmVudC5jaGFuZ2VkVG91Y2hlc1swXSlcbiAgICAgICAgOiBldmVudDtcblxuICAgIHJldHVybiB7XG4gICAgICAgIHg6IHBvaW50LmNsaWVudFgsXG4gICAgICAgIHk6IHBvaW50LmNsaWVudFlcbiAgICB9O1xufVxuXG4vKiogUmV0dXJucyB3aGV0aGVyIGFuIGV2ZW50IGlzIGEgdG91Y2ggZXZlbnQuICovXG5mdW5jdGlvbiBpc1RvdWNoRXZlbnQoZXZlbnQ6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KTogZXZlbnQgaXMgVG91Y2hFdmVudCB7XG4gICAgcmV0dXJuIGV2ZW50LnR5cGVbMF0gPT09IFwidFwiO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcm91bmQobjogbnVtYmVyKSB7XG4gICAgcmV0dXJuIE1hdGgucm91bmQobik7XG59XG5cbi8qKlxuICogU2ltcGxlIG9iamVjdCBjaGVjay5cbiAqIEBwYXJhbSBpdGVtXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0KGl0ZW0pIHtcbiAgICByZXR1cm4gKGl0ZW0gJiYgdHlwZW9mIGl0ZW0gPT09IFwib2JqZWN0XCIgJiYgIUFycmF5LmlzQXJyYXkoaXRlbSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VEZWVwPFQsIFU+KHRhcmdldDogVCwgc291cmNlOiBVKTogVCAmIFU7XG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VEZWVwPFQsIFUsIFY+KHRhcmdldDogVCwgc291cmNlMTogVSwgc291cmNlMjogVik6IFQgJiBVICYgVjtcbmV4cG9ydCBmdW5jdGlvbiBtZXJnZURlZXA8VCwgVSwgViwgVz4odGFyZ2V0OiBULCBzb3VyY2UxOiBVLCBzb3VyY2UyOiBWLCBzb3VyY2UzOiBXKTogVCAmIFUgJiBWICYgVztcbmV4cG9ydCBmdW5jdGlvbiBtZXJnZURlZXAodGFyZ2V0OiBvYmplY3QsIC4uLnNvdXJjZXM6IGFueVtdKTogYW55O1xuXG4vKipcbiAqIERlZXAgbWVyZ2UgdHdvIG9iamVjdHMuXG4gKiBAcGFyYW0gdGFyZ2V0XG4gKiBAcGFyYW0gLi4uc291cmNlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VEZWVwKHRhcmdldDogYW55LCAuLi5zb3VyY2VzOiBhbnlbXSkge1xuICAgIGlmICghc291cmNlcy5sZW5ndGgpIHsgcmV0dXJuIHRhcmdldDsgfVxuICAgIGNvbnN0IHNvdXJjZSA9IHNvdXJjZXMuc2hpZnQoKTtcblxuICAgIGlmIChpc09iamVjdCh0YXJnZXQpICYmIGlzT2JqZWN0KHNvdXJjZSkpIHtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gc291cmNlKSB7XG4gICAgICAgICAgICBpZiAoaXNPYmplY3Qoc291cmNlW2tleV0pKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0YXJnZXRba2V5XSkgeyBPYmplY3QuYXNzaWduKHRhcmdldCwgeyBba2V5XToge30gfSk7IH1cbiAgICAgICAgICAgICAgICBtZXJnZURlZXAodGFyZ2V0W2tleV0sIHNvdXJjZVtrZXldKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgT2JqZWN0LmFzc2lnbih0YXJnZXQsIHsgW2tleV06IHNvdXJjZVtrZXldIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG1lcmdlRGVlcCh0YXJnZXQsIC4uLnNvdXJjZXMpO1xufVxuXG5cbi8qKlxuICogV2UgaGF2ZSB0aGUgY3JvcHBlciBhcmVhIGluIHRoZSBzYW1lIGZpbGUgdG8gZml4IHRoZSBidWlsZFxuICovXG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiBcIm5pY2UtY3JvcHBlci1hcmVhXCIsXG4gICAgdGVtcGxhdGVVcmw6IFwiLi9pbWFnZS1jcm9wcGVyLWFyZWEudGVtcGxhdGUuaHRtbFwiLFxuICAgIHN0eWxlVXJsczogW1wiLi9pbWFnZS1jcm9wcGVyLWFyZWEuc3R5bGUuc2Nzc1wiXSxcbiAgICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIE5pY2VDcm9wcGVyQXJlYUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG4gICAgQFZpZXdDaGlsZChcInJlc2l6ZXJcIilcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9yZXNpemVyPzogRWxlbWVudFJlZjtcblxuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIGtlZXBBc3BlY3RSYXRpbzogYm9vbGVhbjtcblxuICAgIEBJbnB1dCgpXG4gICAgQEhvc3RCaW5kaW5nKFwiY2xhc3Mucm91bmRcIilcbiAgICBwdWJsaWMgcm91bmQ6IGJvb2xlYW47XG5cbiAgICAvKiogVXNlZCB0byBzdWJzY3JpYmUgdG8gZ2xvYmFsIG1vdmUgYW5kIGVuZCBldmVudHMgKi9cbiAgICBwcm90ZWN0ZWQgX2RvY3VtZW50OiBEb2N1bWVudDtcbiAgICBwcml2YXRlIF9pc1NsaWRpbmc6IGJvb2xlYW47XG5cbiAgICAvKiogS2VlcHMgdHJhY2sgb2YgdGhlIGxhc3QgcG9pbnRlciBldmVudCB0aGF0IHdhcyBjYXB0dXJlZCBieSB0aGUgY3JvcCBhcmVhLiAqL1xuICAgIHByaXZhdGUgX2xhc3RQb2ludGVyRXZlbnQ6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50IHwgbnVsbDtcbiAgICBwcml2YXRlIF9zdGFydFBvaW50ZXJFdmVudDoge1xuICAgICAgICB4OiBudW1iZXJcbiAgICAgICAgeTogbnVtYmVyXG4gICAgfSB8IG51bGw7XG4gICAgcHJpdmF0ZSBfY3VycmVudFdpZHRoOiBudW1iZXI7XG4gICAgcHJpdmF0ZSBfY3VycmVudEhlaWdodDogbnVtYmVyO1xuICAgIHByaXZhdGUgX3N0YXJ0QXJlYVJlY3Q6IERPTVJlY3Q7XG4gICAgcHJpdmF0ZSBfc3RhcnRJbWdSZWN0OiBET01SZWN0O1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIEBJbmplY3QoRE9DVU1FTlQpIF9kb2N1bWVudDogYW55LFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IF9lbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IF9jcm9wcGVyOiBOaWNlSW1hZ2VDcm9wcGVyQ29tcG9uZW50LFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IF9uZ1pvbmU6IE5nWm9uZSxcbiAgICApIHtcbiAgICAgICAgdGhpcy5fZG9jdW1lbnQgPSBfZG9jdW1lbnQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcmVzaXphYmxlQXJlYTogYm9vbGVhbjtcblxuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHNldCByZXNpemFibGVBcmVhKHZhbDogYm9vbGVhbikge1xuICAgICAgICBpZiAodmFsICE9PSB0aGlzLl9yZXNpemFibGVBcmVhKSB7XG4gICAgICAgICAgICB0aGlzLl9yZXNpemFibGVBcmVhID0gdmFsO1xuICAgICAgICAgICAgUHJvbWlzZS5yZXNvbHZlKG51bGwpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh2YWwpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcmVtb3ZlUmVzaXphYmxlQXJlYSgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9hZGRSZXNpemFibGVBcmVhKCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcmVtb3ZlUmVzaXphYmxlQXJlYSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIHB1YmxpYyBnZXQgcmVzaXphYmxlQXJlYSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jlc2l6YWJsZUFyZWE7XG4gICAgfVxuXG4gICAgcHVibGljIG5nT25EZXN0cm95KCkge1xuICAgICAgICB0aGlzLl9yZW1vdmVSZXNpemFibGVBcmVhKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfYWRkUmVzaXphYmxlQXJlYSgpIHtcbiAgICAgICAgdGhpcy5fbmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLl9yZXNpemVyLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZWRvd25cIiwgdGhpcy5fcG9pbnRlckRvd24sIGFjdGl2ZUV2ZW50T3B0aW9ucyk7XG4gICAgICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaHN0YXJ0XCIsIHRoaXMuX3BvaW50ZXJEb3duLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9yZW1vdmVSZXNpemFibGVBcmVhKCkge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5fcmVzaXplcj8ubmF0aXZlRWxlbWVudDtcbiAgICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX2xhc3RQb2ludGVyRXZlbnQgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5fcmVtb3ZlR2xvYmFsRXZlbnRzKCk7XG4gICAgICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtb3VzZWRvd25cIiwgdGhpcy5fcG9pbnRlckRvd24sIGFjdGl2ZUV2ZW50T3B0aW9ucyk7XG4gICAgICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ0b3VjaHN0YXJ0XCIsIHRoaXMuX3BvaW50ZXJEb3duLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcG9pbnRlckRvd24gPSAoZXZlbnQ6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KSA9PiB7XG4gICAgICAgIC8vIERvbid0IGRvIGFueXRoaW5nIGlmIHRoZVxuICAgICAgICAvLyB1c2VyIGlzIHVzaW5nIGFueXRoaW5nIG90aGVyIHRoYW4gdGhlIG1haW4gbW91c2UgYnV0dG9uLlxuICAgICAgICBpZiAodGhpcy5faXNTbGlkaW5nIHx8ICghaXNUb3VjaEV2ZW50KGV2ZW50KSAmJiBldmVudC5idXR0b24gIT09IDApKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgIHRoaXMuX25nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5faXNTbGlkaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuX2xhc3RQb2ludGVyRXZlbnQgPSBldmVudDtcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0UG9pbnRlckV2ZW50ID0gZ2V0R2VzdHVyZVBvaW50RnJvbUV2ZW50KGV2ZW50KTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0QXJlYVJlY3QgPSB0aGlzLl9jcm9wcGVyLl9hcmVhQ3JvcHBlclJlY3QoKTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0SW1nUmVjdCA9IHRoaXMuX2Nyb3BwZXIuX2NhbnZhc1JlY3QoKTtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICB0aGlzLl9iaW5kR2xvYmFsRXZlbnRzKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcG9pbnRlck1vdmUgPSAoZXZlbnQ6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KSA9PiB7XG4gICAgICAgIGlmICh0aGlzLl9pc1NsaWRpbmcpIHtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICB0aGlzLl9sYXN0UG9pbnRlckV2ZW50ID0gZXZlbnQ7XG4gICAgICAgICAgICBjb25zdCBlbGVtZW50OiBIVE1MRGl2RWxlbWVudCA9IHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcbiAgICAgICAgICAgIGNvbnN0IHt3aWR0aCwgaGVpZ2h0LCBtaW5XaWR0aCwgbWluSGVpZ2h0fSA9IHRoaXMuX2Nyb3BwZXIuY29uZmlnO1xuICAgICAgICAgICAgY29uc3QgcG9pbnQgPSBnZXRHZXN0dXJlUG9pbnRGcm9tRXZlbnQoZXZlbnQpO1xuICAgICAgICAgICAgY29uc3QgZGVsdGFYID0gcG9pbnQueCAtIHRoaXMuX3N0YXJ0UG9pbnRlckV2ZW50Lng7XG4gICAgICAgICAgICBjb25zdCBkZWx0YVkgPSBwb2ludC55IC0gdGhpcy5fc3RhcnRQb2ludGVyRXZlbnQueTtcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0QXJlYVJlY3QgPSB0aGlzLl9zdGFydEFyZWFSZWN0O1xuICAgICAgICAgICAgY29uc3Qgc3RhcnRJbWdSZWN0ID0gdGhpcy5fc3RhcnRJbWdSZWN0O1xuICAgICAgICAgICAgY29uc3QgaXNSb3VuZCA9IHRoaXMucm91bmQ7XG4gICAgICAgICAgICBjb25zdCBrZWVwQXNwZWN0UmF0aW8gPSB0aGlzLl9jcm9wcGVyLmNvbmZpZy5rZWVwQXNwZWN0UmF0aW8gfHwgZXZlbnQuc2hpZnRLZXk7XG4gICAgICAgICAgICBsZXQgbmV3V2lkdGggPSAwO1xuICAgICAgICAgICAgbGV0IG5ld0hlaWdodCA9IDA7XG4gICAgICAgICAgICBjb25zdCByb290UmVjdCA9IHRoaXMuX2Nyb3BwZXIuX3Jvb3RSZWN0KCk7XG5cbiAgICAgICAgICAgIGlmIChpc1JvdW5kKSB7XG4gICAgICAgICAgICAgICAgLy8gVGhlIGRpc3RhbmNlIGZyb20gdGhlIGNlbnRlciBvZiB0aGUgY3JvcHBlciBhcmVhIHRvIHRoZSBwb2ludGVyXG4gICAgICAgICAgICAgICAgY29uc3Qgb3JpZ2luWCA9ICgod2lkdGggLyAyIC8gTWF0aC5zcXJ0KDIpKSArIGRlbHRhWCk7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3JpZ2luWSA9ICgoaGVpZ2h0IC8gMiAvIE1hdGguc3FydCgyKSkgKyBkZWx0YVkpO1xuXG4gICAgICAgICAgICAgICAgLy8gTGVnXG4gICAgICAgICAgICAgICAgY29uc3Qgc2lkZSA9IE1hdGguc3FydChvcmlnaW5YICoqIDIgKyBvcmlnaW5ZICoqIDIpO1xuICAgICAgICAgICAgICAgIG5ld1dpZHRoID0gbmV3SGVpZ2h0ID0gc2lkZSAqIDI7XG5cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoa2VlcEFzcGVjdFJhdGlvKSB7XG4gICAgICAgICAgICAgICAgbmV3V2lkdGggPSB3aWR0aCArIGRlbHRhWCAqIDI7XG4gICAgICAgICAgICAgICAgbmV3SGVpZ2h0ID0gaGVpZ2h0ICsgZGVsdGFZICogMjtcbiAgICAgICAgICAgICAgICBpZiAod2lkdGggIT09IGhlaWdodCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAod2lkdGggPiBoZWlnaHQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0hlaWdodCA9IGhlaWdodCAvICh3aWR0aCAvIG5ld1dpZHRoKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChoZWlnaHQgPiB3aWR0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3V2lkdGggPSB3aWR0aCAvIChoZWlnaHQgLyBuZXdIZWlnaHQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3V2lkdGggPSBuZXdIZWlnaHQgPSBNYXRoLm1heChuZXdXaWR0aCwgbmV3SGVpZ2h0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG5ld1dpZHRoID0gd2lkdGggKyBkZWx0YVggKiAyO1xuICAgICAgICAgICAgICAgIG5ld0hlaWdodCA9IGhlaWdodCArIGRlbHRhWSAqIDI7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFRvIG1pbiB3aWR0aFxuICAgICAgICAgICAgaWYgKG5ld1dpZHRoIDwgbWluV2lkdGgpIHtcbiAgICAgICAgICAgICAgICBuZXdXaWR0aCA9IG1pbldpZHRoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gVG8gbWluIGhlaWdodFxuICAgICAgICAgICAgaWYgKG5ld0hlaWdodCA8IG1pbkhlaWdodCkge1xuICAgICAgICAgICAgICAgIG5ld0hlaWdodCA9IG1pbkhlaWdodDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRG8gbm90IG92ZXJmbG93IHRoZSBjcm9wcGVyIGFyZWFcbiAgICAgICAgICAgIGNvbnN0IGNlbnRlclggPSBzdGFydEFyZWFSZWN0LnggKyBzdGFydEFyZWFSZWN0LndpZHRoIC8gMjtcbiAgICAgICAgICAgIGNvbnN0IGNlbnRlclkgPSBzdGFydEFyZWFSZWN0LnkgKyBzdGFydEFyZWFSZWN0LmhlaWdodCAvIDI7XG4gICAgICAgICAgICBjb25zdCB0b3BPdmVyZmxvdyA9IHN0YXJ0SW1nUmVjdC55ID4gY2VudGVyWSAtIChuZXdIZWlnaHQgLyAyKTtcbiAgICAgICAgICAgIGNvbnN0IGJvdHRvbU92ZXJmbG93ID0gY2VudGVyWSArIChuZXdIZWlnaHQgLyAyKSA+IHN0YXJ0SW1nUmVjdC5ib3R0b207XG4gICAgICAgICAgICBjb25zdCBtaW5IZWlnaHRPbk92ZXJmbG93ID0gTWF0aC5taW4oKGNlbnRlclkgLSBzdGFydEltZ1JlY3QueSkgKiAyLCAoc3RhcnRJbWdSZWN0LmJvdHRvbSAtIGNlbnRlclkpICogMik7XG4gICAgICAgICAgICBjb25zdCBsZWZ0T3ZlcmZsb3cgPSBzdGFydEltZ1JlY3QueCA+IGNlbnRlclggLSAobmV3V2lkdGggLyAyKTtcbiAgICAgICAgICAgIGNvbnN0IHJpZ2h0T3ZlcmZsb3cgPSBjZW50ZXJYICsgKG5ld1dpZHRoIC8gMikgPiBzdGFydEltZ1JlY3QucmlnaHQ7XG4gICAgICAgICAgICBjb25zdCBtaW5XaWR0aE9uT3ZlcmZsb3cgPSBNYXRoLm1pbigoY2VudGVyWCAtIHN0YXJ0SW1nUmVjdC54KSAqIDIsIChzdGFydEltZ1JlY3QucmlnaHQgLSBjZW50ZXJYKSAqIDIpO1xuICAgICAgICAgICAgY29uc3QgbWluT25PdmVyZmxvdyA9IE1hdGgubWluKG1pbldpZHRoT25PdmVyZmxvdywgbWluSGVpZ2h0T25PdmVyZmxvdyk7XG4gICAgICAgICAgICBpZiAocm91bmQpIHtcbiAgICAgICAgICAgICAgICBpZiAodG9wT3ZlcmZsb3cgfHwgYm90dG9tT3ZlcmZsb3cgfHwgbGVmdE92ZXJmbG93IHx8IHJpZ2h0T3ZlcmZsb3cpIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3SGVpZ2h0ID0gbmV3V2lkdGggPSBtaW5Pbk92ZXJmbG93O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoa2VlcEFzcGVjdFJhdGlvKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbmV3TmV3V2lkdGg6IG51bWJlcltdID0gW107XG4gICAgICAgICAgICAgICAgY29uc3QgbmV3TmV3SGVpZ2h0OiBudW1iZXJbXSA9IFtdO1xuICAgICAgICAgICAgICAgIGlmICgodG9wT3ZlcmZsb3cgfHwgYm90dG9tT3ZlcmZsb3cpICYmIE1hdGgubWluKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3SGVpZ2h0ID0gbWluSGVpZ2h0T25PdmVyZmxvdztcbiAgICAgICAgICAgICAgICAgICAgbmV3TmV3SGVpZ2h0LnB1c2gobmV3SGVpZ2h0KTtcbiAgICAgICAgICAgICAgICAgICAgbmV3V2lkdGggPSB3aWR0aCAvIChoZWlnaHQgLyBtaW5IZWlnaHRPbk92ZXJmbG93KTtcbiAgICAgICAgICAgICAgICAgICAgbmV3TmV3V2lkdGgucHVzaChuZXdXaWR0aCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICgobGVmdE92ZXJmbG93IHx8IHJpZ2h0T3ZlcmZsb3cpKSB7XG4gICAgICAgICAgICAgICAgICAgIG5ld1dpZHRoID0gbWluV2lkdGhPbk92ZXJmbG93O1xuICAgICAgICAgICAgICAgICAgICBuZXdOZXdXaWR0aC5wdXNoKG5ld1dpZHRoKTtcbiAgICAgICAgICAgICAgICAgICAgbmV3SGVpZ2h0ID0gaGVpZ2h0IC8gKHdpZHRoIC8gbWluV2lkdGhPbk92ZXJmbG93KTtcbiAgICAgICAgICAgICAgICAgICAgbmV3TmV3SGVpZ2h0LnB1c2gobmV3SGVpZ2h0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG5ld05ld1dpZHRoLmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgICAgICAgICAgICBuZXdXaWR0aCA9IE1hdGgubWluKC4uLm5ld05ld1dpZHRoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG5ld05ld0hlaWdodC5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3SGVpZ2h0ID0gTWF0aC5taW4oLi4ubmV3TmV3SGVpZ2h0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmICh0b3BPdmVyZmxvdyB8fCBib3R0b21PdmVyZmxvdykge1xuICAgICAgICAgICAgICAgICAgICBuZXdIZWlnaHQgPSBtaW5IZWlnaHRPbk92ZXJmbG93O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAobGVmdE92ZXJmbG93IHx8IHJpZ2h0T3ZlcmZsb3cpIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3V2lkdGggPSBtaW5XaWR0aE9uT3ZlcmZsb3c7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBEbyBub3Qgb3ZlcmZsb3cgdGhlIGNvbnRhaW5lclxuICAgICAgICAgICAgaWYgKHJvdW5kKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbWluID0gTWF0aC5taW4ocm9vdFJlY3Qud2lkdGgsIHJvb3RSZWN0LmhlaWdodCk7XG4gICAgICAgICAgICAgICAgaWYgKG5ld1dpZHRoID4gbWluKSB7XG4gICAgICAgICAgICAgICAgICAgIG5ld1dpZHRoID0gbmV3SGVpZ2h0ID0gbWluO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobmV3SGVpZ2h0ID4gbWluKSB7XG4gICAgICAgICAgICAgICAgICAgIG5ld1dpZHRoID0gbmV3SGVpZ2h0ID0gbWluO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoa2VlcEFzcGVjdFJhdGlvKSB7XG4gICAgICAgICAgICAgICAgaWYgKG5ld1dpZHRoID4gcm9vdFJlY3Qud2lkdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3V2lkdGggPSByb290UmVjdC53aWR0aDtcbiAgICAgICAgICAgICAgICAgICAgbmV3SGVpZ2h0ID0gaGVpZ2h0IC8gKHdpZHRoIC8gcm9vdFJlY3Qud2lkdGgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobmV3SGVpZ2h0ID4gcm9vdFJlY3QuaGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgICAgIG5ld1dpZHRoID0gd2lkdGggLyAoaGVpZ2h0IC8gcm9vdFJlY3QuaGVpZ2h0KTtcbiAgICAgICAgICAgICAgICAgICAgbmV3SGVpZ2h0ID0gcm9vdFJlY3QuaGVpZ2h0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKG5ld1dpZHRoID4gcm9vdFJlY3Qud2lkdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3V2lkdGggPSByb290UmVjdC53aWR0aDtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5ld0hlaWdodCA+IHJvb3RSZWN0LmhlaWdodCkge1xuICAgICAgICAgICAgICAgICAgICBuZXdIZWlnaHQgPSByb290UmVjdC5oZWlnaHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgIC8vIHJvdW5kIHZhbHVlc1xuICAgICAgICAgICAgbmV3V2lkdGggPSBNYXRoLnJvdW5kKG5ld1dpZHRoKTtcbiAgICAgICAgICAgIG5ld0hlaWdodCA9IE1hdGgucm91bmQobmV3SGVpZ2h0KTtcblxuICAgICAgICAgICAgZWxlbWVudC5zdHlsZS53aWR0aCA9IGAke25ld1dpZHRofXB4YDtcbiAgICAgICAgICAgIGVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gYCR7bmV3SGVpZ2h0fXB4YDtcbiAgICAgICAgICAgIHRoaXMuX2N1cnJlbnRXaWR0aCA9IG5ld1dpZHRoO1xuICAgICAgICAgICAgdGhpcy5fY3VycmVudEhlaWdodCA9IG5ld0hlaWdodDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBDYWxsZWQgd2hlbiB0aGUgdXNlciBoYXMgbGlmdGVkIHRoZWlyIHBvaW50ZXIuICovXG4gICAgcHJpdmF0ZSBfcG9pbnRlclVwID0gKGV2ZW50OiBUb3VjaEV2ZW50IHwgTW91c2VFdmVudCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5faXNTbGlkaW5nKSB7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgdGhpcy5fcmVtb3ZlR2xvYmFsRXZlbnRzKCk7XG4gICAgICAgICAgICB0aGlzLl9jcm9wcGVyLl9wcmltYXJ5QXJlYVdpZHRoID0gdGhpcy5fY3JvcHBlci5jb25maWcud2lkdGggPSB0aGlzLl9jdXJyZW50V2lkdGg7XG4gICAgICAgICAgICB0aGlzLl9jcm9wcGVyLl9wcmltYXJ5QXJlYUhlaWdodCA9IHRoaXMuX2Nyb3BwZXIuY29uZmlnLmhlaWdodCA9IHRoaXMuX2N1cnJlbnRIZWlnaHQ7XG4gICAgICAgICAgICB0aGlzLl9jcm9wcGVyLmNvbmZpZyA9IHRoaXMuX2Nyb3BwZXIuY29uZmlnO1xuICAgICAgICAgICAgdGhpcy5fY3JvcHBlci5fdXBkYXRlTWluU2NhbGUoKTtcbiAgICAgICAgICAgIHRoaXMuX2lzU2xpZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5fc3RhcnRQb2ludGVyRXZlbnQgPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIENhbGxlZCB3aGVuIHRoZSB3aW5kb3cgaGFzIGxvc3QgZm9jdXMuICovXG4gICAgcHJpdmF0ZSBfd2luZG93Qmx1ciA9ICgpID0+IHtcbiAgICAgICAgLy8gSWYgdGhlIHdpbmRvdyBpcyBibHVycmVkIHdoaWxlIGRyYWdnaW5nIHdlIG5lZWQgdG8gc3RvcCBkcmFnZ2luZyBiZWNhdXNlIHRoZVxuICAgICAgICAvLyBicm93c2VyIHdvbid0IGRpc3BhdGNoIHRoZSBgbW91c2V1cGAgYW5kIGB0b3VjaGVuZGAgZXZlbnRzIGFueW1vcmUuXG4gICAgICAgIGlmICh0aGlzLl9sYXN0UG9pbnRlckV2ZW50KSB7XG4gICAgICAgICAgICB0aGlzLl9wb2ludGVyVXAodGhpcy5fbGFzdFBvaW50ZXJFdmVudCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIF9iaW5kR2xvYmFsRXZlbnRzKHRyaWdnZXJFdmVudDogVG91Y2hFdmVudCB8IE1vdXNlRXZlbnQpIHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuX2RvY3VtZW50O1xuICAgICAgICBjb25zdCBpc1RvdWNoID0gaXNUb3VjaEV2ZW50KHRyaWdnZXJFdmVudCk7XG4gICAgICAgIGNvbnN0IG1vdmVFdmVudE5hbWUgPSBpc1RvdWNoID8gXCJ0b3VjaG1vdmVcIiA6IFwibW91c2Vtb3ZlXCI7XG4gICAgICAgIGNvbnN0IGVuZEV2ZW50TmFtZSA9IGlzVG91Y2ggPyBcInRvdWNoZW5kXCIgOiBcIm1vdXNldXBcIjtcbiAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKG1vdmVFdmVudE5hbWUsIHRoaXMuX3BvaW50ZXJNb3ZlLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoZW5kRXZlbnROYW1lLCB0aGlzLl9wb2ludGVyVXAsIGFjdGl2ZUV2ZW50T3B0aW9ucyk7XG5cbiAgICAgICAgaWYgKGlzVG91Y2gpIHtcbiAgICAgICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNoY2FuY2VsXCIsIHRoaXMuX3BvaW50ZXJVcCwgYWN0aXZlRXZlbnRPcHRpb25zKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHdpbmRvdyA9IHRoaXMuX2dldFdpbmRvdygpO1xuXG4gICAgICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiICYmIHdpbmRvdykge1xuICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJibHVyXCIsIHRoaXMuX3dpbmRvd0JsdXIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIFJlbW92ZXMgYW55IGdsb2JhbCBldmVudCBsaXN0ZW5lcnMgdGhhdCB3ZSBtYXkgaGF2ZSBhZGRlZC4gKi9cbiAgICBwcml2YXRlIF9yZW1vdmVHbG9iYWxFdmVudHMoKSB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLl9kb2N1bWVudDtcbiAgICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2Vtb3ZlXCIsIHRoaXMuX3BvaW50ZXJNb3ZlLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtb3VzZXVwXCIsIHRoaXMuX3BvaW50ZXJVcCwgYWN0aXZlRXZlbnRPcHRpb25zKTtcbiAgICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2htb3ZlXCIsIHRoaXMuX3BvaW50ZXJNb3ZlLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ0b3VjaGVuZFwiLCB0aGlzLl9wb2ludGVyVXAsIGFjdGl2ZUV2ZW50T3B0aW9ucyk7XG4gICAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRvdWNoY2FuY2VsXCIsIHRoaXMuX3BvaW50ZXJVcCwgYWN0aXZlRXZlbnRPcHRpb25zKTtcblxuICAgICAgICBjb25zdCB3aW5kb3cgPSB0aGlzLl9nZXRXaW5kb3coKTtcblxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJiB3aW5kb3cpIHtcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFwiYmx1clwiLCB0aGlzLl93aW5kb3dCbHVyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBVc2UgZGVmYXVsdFZpZXcgb2YgaW5qZWN0ZWQgZG9jdW1lbnQgaWYgYXZhaWxhYmxlIG9yIGZhbGxiYWNrIHRvIGdsb2JhbCB3aW5kb3cgcmVmZXJlbmNlICovXG4gICAgcHJpdmF0ZSBfZ2V0V2luZG93KCk6IFdpbmRvdyB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kb2N1bWVudC5kZWZhdWx0VmlldyB8fCB3aW5kb3c7XG4gICAgfVxufVxuIiwiPCEtLSAoc2VsZWN0c3RhcnQpOiBPbiBTYWZhcmkgc3RhcnRpbmcgdG8gc2xpZGUgdGVtcG9yYXJpbHkgdHJpZ2dlcnMgdGV4dCBzZWxlY3Rpb24gbW9kZSB3aGljaFxuc2hvdyB0aGUgd3JvbmcgY3Vyc29yLiBXZSBwcmV2ZW50IGl0IGJ5IHN0b3BwaW5nIHRoZSBgc2VsZWN0c3RhcnRgIGV2ZW50LiAtLT5cbjxkaXYgY2xhc3M9XCJpbWFnZS1jb250YWluZXJcIiAjX2ltZ0NvbnRhaW5lclxuICAgICAoc2VsZWN0c3RhcnQpPVwiJGV2ZW50LnByZXZlbnREZWZhdWx0KClcIlxuPlxuICAgIDxjYW52YXMgI19pbWdDYW52YXM+PC9jYW52YXM+XG48L2Rpdj5cbjxuaWNlLWNyb3BwZXItYXJlYVxuICAgICNfYXJlYVxuICAgICpuZ0lmPVwiX2lzTG9hZGVkSW1nXCJcbiAgICBbcm91bmRdPVwiISFjb25maWcucm91bmRcIlxuICAgIFtyZXNpemFibGVBcmVhXT1cIiEhY29uZmlnLnJlc2l6YWJsZUFyZWFcIlxuICAgIFtrZWVwQXNwZWN0UmF0aW9dPVwiISFjb25maWcua2VlcEFzcGVjdFJhdGlvXCJcbiAgICBbbmdTdHlsZV09XCJ7XG4gICAgICAgIHdpZHRoOiBjb25maWcud2lkdGggKyAncHgnLFxuICAgICAgICBoZWlnaHQ6IGNvbmZpZy5oZWlnaHQgKyAncHgnXG4gICAgfVwiXG4+PC9uaWNlLWNyb3BwZXItYXJlYT5cbjxidXR0b24gY2xhc3M9XCJjbG9zZS1idXR0b25cIiBtYXQtaWNvbi1idXR0b24gKm5nSWY9XCJfaXNMb2FkZWRJbWdcIiAoY2xpY2spPVwiY2xlYW4oKVwiPlxuICAgIDxtYXQtaWNvbj5hcnJvd19iYWNrPC9tYXQtaWNvbj5cbjwvYnV0dG9uPlxuIiwiPGRpdiBjbGFzcz1cInJlc2l6ZXJcIiAjcmVzaXplciAqbmdJZj1cInJlc2l6YWJsZUFyZWFcIj48L2Rpdj5cbiJdfQ==
|