@ng-matero/extensions 15.5.0 → 16.0.0
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/alert/alert.d.ts +1 -1
- package/button/button-loading.d.ts +1 -1
- package/checkbox-group/checkbox-group.d.ts +1 -1
- package/colorpicker/colorpicker-input.d.ts +1 -1
- package/colorpicker/colorpicker-toggle.d.ts +1 -1
- package/colorpicker/colorpicker.d.ts +2 -2
- package/datetimepicker/calendar-body.d.ts +1 -1
- package/datetimepicker/calendar.d.ts +1 -1
- package/datetimepicker/clock.d.ts +1 -1
- package/datetimepicker/clock.scss +1 -4
- package/datetimepicker/datetimepicker-input.d.ts +1 -1
- package/datetimepicker/datetimepicker-toggle.d.ts +1 -1
- package/datetimepicker/datetimepicker.d.ts +2 -2
- package/datetimepicker/month-view.d.ts +1 -1
- package/datetimepicker/multi-year-view.d.ts +1 -1
- package/datetimepicker/time.d.ts +2 -2
- package/datetimepicker/year-view.d.ts +1 -1
- package/esm2022/alert/alert-module.mjs +19 -0
- package/esm2022/alert/alert.mjs +53 -0
- package/esm2022/button/button-loading.mjs +77 -0
- package/esm2022/button/button-module.mjs +21 -0
- package/esm2022/checkbox-group/checkbox-group-module.mjs +22 -0
- package/esm2022/checkbox-group/checkbox-group.mjs +234 -0
- package/esm2022/colorpicker/colorpicker-input.mjs +229 -0
- package/esm2022/colorpicker/colorpicker-module.mjs +64 -0
- package/esm2022/colorpicker/colorpicker-toggle.mjs +103 -0
- package/esm2022/colorpicker/colorpicker.mjs +367 -0
- package/esm2022/column-resize/column-resize-directives/column-resize-flex.mjs +46 -0
- package/esm2022/column-resize/column-resize-directives/column-resize.mjs +46 -0
- package/esm2022/column-resize/column-resize-module.mjs +29 -0
- package/esm2022/column-resize/column-resize-notifier.mjs +49 -0
- package/esm2022/column-resize/column-resize.mjs +83 -0
- package/esm2022/column-resize/column-size-store.mjs +21 -0
- package/esm2022/column-resize/event-dispatcher.mjs +68 -0
- package/esm2022/column-resize/overlay-handle.mjs +147 -0
- package/esm2022/column-resize/resizable.mjs +200 -0
- package/esm2022/column-resize/resize-strategy.mjs +235 -0
- package/{esm2020 → esm2022}/core/datetime/datetime-adapter.mjs +1 -1
- package/esm2022/core/datetime/datetime.module.mjs +44 -0
- package/esm2022/core/datetime/native-datetime-adapter.mjs +139 -0
- package/esm2022/core/pipes/is-template-ref.pipe.mjs +15 -0
- package/esm2022/core/pipes/pipes.module.mjs +20 -0
- package/esm2022/core/pipes/to-observable.pipe.mjs +16 -0
- package/esm2022/datetimepicker/calendar-body.mjs +79 -0
- package/esm2022/datetimepicker/calendar.mjs +672 -0
- package/esm2022/datetimepicker/clock.mjs +354 -0
- package/esm2022/datetimepicker/datetimepicker-input.mjs +350 -0
- package/esm2022/datetimepicker/datetimepicker-intl.mjs +64 -0
- package/esm2022/datetimepicker/datetimepicker-module.mjs +83 -0
- package/esm2022/datetimepicker/datetimepicker-toggle.mjs +106 -0
- package/esm2022/datetimepicker/datetimepicker.mjs +529 -0
- package/esm2022/datetimepicker/month-view.mjs +149 -0
- package/esm2022/datetimepicker/multi-year-view.mjs +215 -0
- package/esm2022/datetimepicker/time.mjs +458 -0
- package/esm2022/datetimepicker/year-view.mjs +139 -0
- package/esm2022/dialog/dialog-container.mjs +36 -0
- package/esm2022/dialog/dialog-module.mjs +25 -0
- package/esm2022/dialog/dialog.mjs +75 -0
- package/esm2022/drawer/drawer-container.mjs +253 -0
- package/esm2022/drawer/drawer-module.mjs +23 -0
- package/esm2022/drawer/drawer.mjs +167 -0
- package/esm2022/grid/cell.mjs +117 -0
- package/{esm2020 → esm2022}/grid/column-menu.mjs +6 -5
- package/esm2022/grid/column-resize/column-resize-directives/column-resize-flex.mjs +38 -0
- package/esm2022/grid/column-resize/column-resize-directives/column-resize.mjs +38 -0
- package/esm2022/grid/column-resize/column-resize-module.mjs +44 -0
- package/esm2022/grid/column-resize/overlay-handle.mjs +61 -0
- package/esm2022/grid/column-resize/resizable-directives/resizable.mjs +63 -0
- package/esm2022/grid/column-resize/resize-strategy.mjs +43 -0
- package/esm2022/grid/expansion-toggle.mjs +65 -0
- package/esm2022/grid/grid-module.mjs +137 -0
- package/esm2022/grid/grid-pipes.mjs +113 -0
- package/esm2022/grid/grid-utils.mjs +64 -0
- package/esm2022/grid/grid.mjs +630 -0
- package/esm2022/loader/loader-module.mjs +21 -0
- package/esm2022/loader/loader.mjs +70 -0
- package/esm2022/popover/popover-content.mjs +92 -0
- package/esm2022/popover/popover-module.mjs +25 -0
- package/esm2022/popover/popover-target.mjs +18 -0
- package/esm2022/popover/popover-trigger.mjs +472 -0
- package/esm2022/popover/popover.mjs +384 -0
- package/esm2022/progress/progress-module.mjs +19 -0
- package/esm2022/progress/progress.mjs +56 -0
- package/esm2022/select/option.mjs +58 -0
- package/esm2022/select/select-module.mjs +75 -0
- package/esm2022/select/select.mjs +561 -0
- package/esm2022/select/templates.mjs +135 -0
- package/esm2022/slider/slider-module.mjs +20 -0
- package/esm2022/slider/slider.mjs +1116 -0
- package/esm2022/split/split-module.mjs +20 -0
- package/esm2022/split/split-pane.mjs +150 -0
- package/esm2022/split/split.mjs +635 -0
- package/esm2022/tooltip/tooltip-module.mjs +25 -0
- package/esm2022/tooltip/tooltip.mjs +930 -0
- package/{fesm2020 → fesm2022}/mtxAlert.mjs +7 -7
- package/{fesm2020 → fesm2022}/mtxAlert.mjs.map +1 -1
- package/{fesm2020 → fesm2022}/mtxButton.mjs +7 -7
- package/{fesm2015 → fesm2022}/mtxButton.mjs.map +1 -1
- package/{fesm2020 → fesm2022}/mtxCheckboxGroup.mjs +13 -13
- package/{fesm2020 → fesm2022}/mtxCheckboxGroup.mjs.map +1 -1
- package/{fesm2020 → fesm2022}/mtxColorpicker.mjs +41 -41
- package/{fesm2020 → fesm2022}/mtxColorpicker.mjs.map +1 -1
- package/{fesm2020 → fesm2022}/mtxColumnResize.mjs +46 -46
- package/{fesm2015 → fesm2022}/mtxColumnResize.mjs.map +1 -1
- package/{fesm2020 → fesm2022}/mtxCore.mjs +26 -26
- package/fesm2022/mtxCore.mjs.map +1 -0
- package/{fesm2020 → fesm2022}/mtxDatetimepicker.mjs +84 -80
- package/fesm2022/mtxDatetimepicker.mjs.map +1 -0
- package/{fesm2020 → fesm2022}/mtxDialog.mjs +10 -10
- package/{fesm2015 → fesm2022}/mtxDialog.mjs.map +1 -1
- package/{fesm2020 → fesm2022}/mtxDrawer.mjs +10 -10
- package/{fesm2020 → fesm2022}/mtxDrawer.mjs.map +1 -1
- package/{fesm2020 → fesm2022}/mtxGrid.mjs +120 -120
- package/{fesm2020 → fesm2022}/mtxGrid.mjs.map +1 -1
- package/{fesm2020 → fesm2022}/mtxLoader.mjs +7 -7
- package/{fesm2020 → fesm2022}/mtxLoader.mjs.map +1 -1
- package/{fesm2020 → fesm2022}/mtxPopover.mjs +19 -19
- package/{fesm2020 → fesm2022}/mtxPopover.mjs.map +1 -1
- package/{fesm2020 → fesm2022}/mtxProgress.mjs +7 -7
- package/{fesm2015 → fesm2022}/mtxProgress.mjs.map +1 -1
- package/{fesm2020 → fesm2022}/mtxSelect.mjs +68 -68
- package/{fesm2015 → fesm2022}/mtxSelect.mjs.map +1 -1
- package/{fesm2020 → fesm2022}/mtxSlider.mjs +7 -7
- package/{fesm2020 → fesm2022}/mtxSlider.mjs.map +1 -1
- package/{fesm2020 → fesm2022}/mtxSplit.mjs +10 -10
- package/{fesm2020 → fesm2022}/mtxSplit.mjs.map +1 -1
- package/{fesm2020 → fesm2022}/mtxTooltip.mjs +16 -16
- package/{fesm2015 → fesm2022}/mtxTooltip.mjs.map +1 -1
- package/grid/cell.d.ts +1 -1
- package/grid/column-menu.d.ts +1 -1
- package/grid/column-resize/resizable-directives/resizable.d.ts +1 -1
- package/grid/expansion-toggle.d.ts +1 -1
- package/grid/grid.d.ts +2 -2
- package/loader/loader.d.ts +1 -1
- package/package.json +69 -109
- package/popover/popover-trigger.d.ts +1 -1
- package/popover/popover.d.ts +1 -1
- package/progress/progress.d.ts +1 -1
- package/select/option.d.ts +1 -1
- package/select/select.d.ts +1 -1
- package/select/select.scss +0 -7
- package/slider/slider.d.ts +1 -1
- package/split/split-pane.d.ts +1 -1
- package/split/split.d.ts +1 -1
- package/tooltip/tooltip.d.ts +1 -1
- package/tooltip/tooltip.scss +1 -4
- package/esm2020/alert/alert-module.mjs +0 -18
- package/esm2020/alert/alert.mjs +0 -52
- package/esm2020/button/button-loading.mjs +0 -76
- package/esm2020/button/button-module.mjs +0 -20
- package/esm2020/checkbox-group/checkbox-group-module.mjs +0 -21
- package/esm2020/checkbox-group/checkbox-group.mjs +0 -233
- package/esm2020/colorpicker/colorpicker-input.mjs +0 -228
- package/esm2020/colorpicker/colorpicker-module.mjs +0 -63
- package/esm2020/colorpicker/colorpicker-toggle.mjs +0 -101
- package/esm2020/colorpicker/colorpicker.mjs +0 -365
- package/esm2020/column-resize/column-resize-directives/column-resize-flex.mjs +0 -45
- package/esm2020/column-resize/column-resize-directives/column-resize.mjs +0 -45
- package/esm2020/column-resize/column-resize-module.mjs +0 -28
- package/esm2020/column-resize/column-resize-notifier.mjs +0 -47
- package/esm2020/column-resize/column-resize.mjs +0 -82
- package/esm2020/column-resize/column-size-store.mjs +0 -20
- package/esm2020/column-resize/event-dispatcher.mjs +0 -67
- package/esm2020/column-resize/overlay-handle.mjs +0 -146
- package/esm2020/column-resize/resizable.mjs +0 -199
- package/esm2020/column-resize/resize-strategy.mjs +0 -232
- package/esm2020/core/datetime/datetime.module.mjs +0 -42
- package/esm2020/core/datetime/native-datetime-adapter.mjs +0 -138
- package/esm2020/core/pipes/is-template-ref.pipe.mjs +0 -14
- package/esm2020/core/pipes/pipes.module.mjs +0 -19
- package/esm2020/core/pipes/to-observable.pipe.mjs +0 -15
- package/esm2020/datetimepicker/calendar-body.mjs +0 -78
- package/esm2020/datetimepicker/calendar.mjs +0 -671
- package/esm2020/datetimepicker/clock.mjs +0 -349
- package/esm2020/datetimepicker/datetimepicker-input.mjs +0 -349
- package/esm2020/datetimepicker/datetimepicker-intl.mjs +0 -63
- package/esm2020/datetimepicker/datetimepicker-module.mjs +0 -82
- package/esm2020/datetimepicker/datetimepicker-toggle.mjs +0 -104
- package/esm2020/datetimepicker/datetimepicker.mjs +0 -527
- package/esm2020/datetimepicker/month-view.mjs +0 -148
- package/esm2020/datetimepicker/multi-year-view.mjs +0 -214
- package/esm2020/datetimepicker/time.mjs +0 -456
- package/esm2020/datetimepicker/year-view.mjs +0 -138
- package/esm2020/dialog/dialog-container.mjs +0 -35
- package/esm2020/dialog/dialog-module.mjs +0 -24
- package/esm2020/dialog/dialog.mjs +0 -74
- package/esm2020/drawer/drawer-container.mjs +0 -252
- package/esm2020/drawer/drawer-module.mjs +0 -22
- package/esm2020/drawer/drawer.mjs +0 -166
- package/esm2020/grid/cell.mjs +0 -116
- package/esm2020/grid/column-resize/column-resize-directives/column-resize-flex.mjs +0 -37
- package/esm2020/grid/column-resize/column-resize-directives/column-resize.mjs +0 -37
- package/esm2020/grid/column-resize/column-resize-module.mjs +0 -42
- package/esm2020/grid/column-resize/overlay-handle.mjs +0 -60
- package/esm2020/grid/column-resize/resizable-directives/resizable.mjs +0 -62
- package/esm2020/grid/column-resize/resize-strategy.mjs +0 -42
- package/esm2020/grid/expansion-toggle.mjs +0 -64
- package/esm2020/grid/grid-module.mjs +0 -136
- package/esm2020/grid/grid-pipes.mjs +0 -108
- package/esm2020/grid/grid-utils.mjs +0 -63
- package/esm2020/grid/grid.mjs +0 -628
- package/esm2020/loader/loader-module.mjs +0 -20
- package/esm2020/loader/loader.mjs +0 -69
- package/esm2020/popover/popover-content.mjs +0 -90
- package/esm2020/popover/popover-module.mjs +0 -24
- package/esm2020/popover/popover-target.mjs +0 -17
- package/esm2020/popover/popover-trigger.mjs +0 -471
- package/esm2020/popover/popover.mjs +0 -383
- package/esm2020/progress/progress-module.mjs +0 -18
- package/esm2020/progress/progress.mjs +0 -55
- package/esm2020/select/option.mjs +0 -57
- package/esm2020/select/select-module.mjs +0 -74
- package/esm2020/select/select.mjs +0 -560
- package/esm2020/select/templates.mjs +0 -124
- package/esm2020/slider/slider-module.mjs +0 -19
- package/esm2020/slider/slider.mjs +0 -1115
- package/esm2020/split/split-module.mjs +0 -19
- package/esm2020/split/split-pane.mjs +0 -149
- package/esm2020/split/split.mjs +0 -634
- package/esm2020/tooltip/tooltip-module.mjs +0 -24
- package/esm2020/tooltip/tooltip.mjs +0 -926
- package/fesm2015/mtxAlert.mjs +0 -74
- package/fesm2015/mtxAlert.mjs.map +0 -1
- package/fesm2015/mtxButton.mjs +0 -99
- package/fesm2015/mtxCheckboxGroup.mjs +0 -256
- package/fesm2015/mtxCheckboxGroup.mjs.map +0 -1
- package/fesm2015/mtxColorpicker.mjs +0 -767
- package/fesm2015/mtxColorpicker.mjs.map +0 -1
- package/fesm2015/mtxColumnResize.mjs +0 -959
- package/fesm2015/mtxCore.mjs +0 -374
- package/fesm2015/mtxCore.mjs.map +0 -1
- package/fesm2015/mtxDatetimepicker.mjs +0 -3164
- package/fesm2015/mtxDatetimepicker.mjs.map +0 -1
- package/fesm2015/mtxDialog.mjs +0 -130
- package/fesm2015/mtxDrawer.mjs +0 -578
- package/fesm2015/mtxDrawer.mjs.map +0 -1
- package/fesm2015/mtxGrid.mjs +0 -1514
- package/fesm2015/mtxGrid.mjs.map +0 -1
- package/fesm2015/mtxLoader.mjs +0 -93
- package/fesm2015/mtxLoader.mjs.map +0 -1
- package/fesm2015/mtxPopover.mjs +0 -1027
- package/fesm2015/mtxPopover.mjs.map +0 -1
- package/fesm2015/mtxProgress.mjs +0 -77
- package/fesm2015/mtxSelect.mjs +0 -814
- package/fesm2015/mtxSlider.mjs +0 -1139
- package/fesm2015/mtxSlider.mjs.map +0 -1
- package/fesm2015/mtxSplit.mjs +0 -1025
- package/fesm2015/mtxSplit.mjs.map +0 -1
- package/fesm2015/mtxTooltip.mjs +0 -982
- package/fesm2020/mtxButton.mjs.map +0 -1
- package/fesm2020/mtxColumnResize.mjs.map +0 -1
- package/fesm2020/mtxCore.mjs.map +0 -1
- package/fesm2020/mtxDatetimepicker.mjs.map +0 -1
- package/fesm2020/mtxDialog.mjs.map +0 -1
- package/fesm2020/mtxProgress.mjs.map +0 -1
- package/fesm2020/mtxSelect.mjs.map +0 -1
- package/fesm2020/mtxTooltip.mjs.map +0 -1
- package/fesm2020/ng-matero-extensions.mjs +0 -9
- package/fesm2020/ng-matero-extensions.mjs.map +0 -1
- /package/{esm2020 → esm2022}/alert/mtxAlert.mjs +0 -0
- /package/{esm2020 → esm2022}/alert/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/button/mtxButton.mjs +0 -0
- /package/{esm2020 → esm2022}/button/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/checkbox-group/interfaces.mjs +0 -0
- /package/{esm2020 → esm2022}/checkbox-group/mtxCheckboxGroup.mjs +0 -0
- /package/{esm2020 → esm2022}/checkbox-group/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/colorpicker/colorpicker-animations.mjs +0 -0
- /package/{esm2020 → esm2022}/colorpicker/mtxColorpicker.mjs +0 -0
- /package/{esm2020 → esm2022}/colorpicker/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/column-resize/column-resize-directives/constants.mjs +0 -0
- /package/{esm2020 → esm2022}/column-resize/mtxColumnResize.mjs +0 -0
- /package/{esm2020 → esm2022}/column-resize/polyfill.mjs +0 -0
- /package/{esm2020 → esm2022}/column-resize/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/column-resize/resize-ref.mjs +0 -0
- /package/{esm2020 → esm2022}/column-resize/selectors.mjs +0 -0
- /package/{esm2020 → esm2022}/core/datetime/datetime-formats.mjs +0 -0
- /package/{esm2020 → esm2022}/core/datetime/index.mjs +0 -0
- /package/{esm2020 → esm2022}/core/datetime/native-datetime-formats.mjs +0 -0
- /package/{esm2020 → esm2022}/core/mtxCore.mjs +0 -0
- /package/{esm2020 → esm2022}/core/pipes/index.mjs +0 -0
- /package/{esm2020 → esm2022}/core/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/datetimepicker/datetimepicker-animations.mjs +0 -0
- /package/{esm2020 → esm2022}/datetimepicker/datetimepicker-errors.mjs +0 -0
- /package/{esm2020 → esm2022}/datetimepicker/datetimepicker-filtertype.mjs +0 -0
- /package/{esm2020 → esm2022}/datetimepicker/datetimepicker-types.mjs +0 -0
- /package/{esm2020 → esm2022}/datetimepicker/mtxDatetimepicker.mjs +0 -0
- /package/{esm2020 → esm2022}/datetimepicker/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/dialog/dialog-config.mjs +0 -0
- /package/{esm2020 → esm2022}/dialog/mtxDialog.mjs +0 -0
- /package/{esm2020 → esm2022}/dialog/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/drawer/drawer-animation.mjs +0 -0
- /package/{esm2020 → esm2022}/drawer/drawer-config.mjs +0 -0
- /package/{esm2020 → esm2022}/drawer/drawer-ref.mjs +0 -0
- /package/{esm2020 → esm2022}/drawer/mtxDrawer.mjs +0 -0
- /package/{esm2020 → esm2022}/drawer/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/grid/column-resize/column-resize-directives/common.mjs +0 -0
- /package/{esm2020 → esm2022}/grid/column-resize/resizable-directives/common.mjs +0 -0
- /package/{esm2020 → esm2022}/grid/interfaces.mjs +0 -0
- /package/{esm2020 → esm2022}/grid/mtxGrid.mjs +0 -0
- /package/{esm2020 → esm2022}/grid/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/loader/mtxLoader.mjs +0 -0
- /package/{esm2020 → esm2022}/loader/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/ng-matero-extensions.mjs +0 -0
- /package/{esm2020 → esm2022}/popover/mtxPopover.mjs +0 -0
- /package/{esm2020 → esm2022}/popover/popover-animations.mjs +0 -0
- /package/{esm2020 → esm2022}/popover/popover-errors.mjs +0 -0
- /package/{esm2020 → esm2022}/popover/popover-interfaces.mjs +0 -0
- /package/{esm2020 → esm2022}/popover/popover-types.mjs +0 -0
- /package/{esm2020 → esm2022}/popover/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/progress/mtxProgress.mjs +0 -0
- /package/{esm2020 → esm2022}/progress/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/select/mtxSelect.mjs +0 -0
- /package/{esm2020 → esm2022}/select/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/slider/mtxSlider.mjs +0 -0
- /package/{esm2020 → esm2022}/slider/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/split/interfaces.mjs +0 -0
- /package/{esm2020 → esm2022}/split/mtxSplit.mjs +0 -0
- /package/{esm2020 → esm2022}/split/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/split/utils.mjs +0 -0
- /package/{esm2020 → esm2022}/tooltip/mtxTooltip.mjs +0 -0
- /package/{esm2020 → esm2022}/tooltip/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/tooltip/tooltip-animations.mjs +0 -0
- /package/{fesm2015 → fesm2022}/ng-matero-extensions.mjs +0 -0
- /package/{fesm2015 → fesm2022}/ng-matero-extensions.mjs.map +0 -0
|
@@ -0,0 +1,1116 @@
|
|
|
1
|
+
import { coerceBooleanProperty, coerceNumberProperty, } from '@angular/cdk/coercion';
|
|
2
|
+
import { DOWN_ARROW, END, HOME, LEFT_ARROW, PAGE_DOWN, PAGE_UP, RIGHT_ARROW, UP_ARROW, } from '@angular/cdk/keycodes';
|
|
3
|
+
import { normalizePassiveListenerOptions } from '@angular/cdk/platform';
|
|
4
|
+
import { Attribute, ChangeDetectionStrategy, Component, EventEmitter, forwardRef, Inject, Input, Optional, Output, ViewChild, ViewEncapsulation, } from '@angular/core';
|
|
5
|
+
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
6
|
+
import { mixinColor, mixinDisabled, mixinTabIndex, } from '@angular/material/core';
|
|
7
|
+
import { ANIMATION_MODULE_TYPE } from '@angular/platform-browser/animations';
|
|
8
|
+
import { Subscription } from 'rxjs';
|
|
9
|
+
import * as i0 from "@angular/core";
|
|
10
|
+
import * as i1 from "@angular/cdk/a11y";
|
|
11
|
+
import * as i2 from "@angular/cdk/bidi";
|
|
12
|
+
import * as i3 from "@angular/common";
|
|
13
|
+
const activeEventOptions = normalizePassiveListenerOptions({ passive: false });
|
|
14
|
+
/**
|
|
15
|
+
* Visually, a 30px separation between tick marks looks best. This is very subjective but it is
|
|
16
|
+
* the default separation we chose.
|
|
17
|
+
*/
|
|
18
|
+
const MIN_AUTO_TICK_SEPARATION = 30;
|
|
19
|
+
/** The thumb gap size for a disabled slider. */
|
|
20
|
+
const DISABLED_THUMB_GAP = 0;
|
|
21
|
+
/** The thumb gap size for a non-active slider at its minimum value. */
|
|
22
|
+
const MIN_VALUE_NONACTIVE_THUMB_GAP = 7;
|
|
23
|
+
/** The thumb gap size for an active slider at its minimum value. */
|
|
24
|
+
const MIN_VALUE_ACTIVE_THUMB_GAP = 10;
|
|
25
|
+
/**
|
|
26
|
+
* Provider Expression that allows mtx-slider to register as a ControlValueAccessor.
|
|
27
|
+
* This allows it to support [(ngModel)] and [formControl].
|
|
28
|
+
*/
|
|
29
|
+
export const MTX_SLIDER_VALUE_ACCESSOR = {
|
|
30
|
+
provide: NG_VALUE_ACCESSOR,
|
|
31
|
+
useExisting: forwardRef(() => MtxSlider),
|
|
32
|
+
multi: true,
|
|
33
|
+
};
|
|
34
|
+
/** A simple change event emitted by the MtxSlider component. */
|
|
35
|
+
export class MtxSliderChange {
|
|
36
|
+
}
|
|
37
|
+
// Boilerplate for applying mixins to MtxSlider.
|
|
38
|
+
/** @docs-private */
|
|
39
|
+
const _MtxSliderBase = mixinTabIndex(mixinColor(mixinDisabled(class {
|
|
40
|
+
constructor(_elementRef) {
|
|
41
|
+
this._elementRef = _elementRef;
|
|
42
|
+
}
|
|
43
|
+
}), 'accent'));
|
|
44
|
+
/**
|
|
45
|
+
* Allows users to select from a range of values by moving the slider thumb. It is similar in
|
|
46
|
+
* behavior to the native `<input type="range">` element.
|
|
47
|
+
*/
|
|
48
|
+
class MtxSlider extends _MtxSliderBase {
|
|
49
|
+
/** Whether the slider is inverted. */
|
|
50
|
+
get invert() {
|
|
51
|
+
return this._invert;
|
|
52
|
+
}
|
|
53
|
+
set invert(value) {
|
|
54
|
+
this._invert = coerceBooleanProperty(value);
|
|
55
|
+
}
|
|
56
|
+
/** The maximum value that the slider can have. */
|
|
57
|
+
get max() {
|
|
58
|
+
return this._max;
|
|
59
|
+
}
|
|
60
|
+
set max(v) {
|
|
61
|
+
this._max = coerceNumberProperty(v, this._max);
|
|
62
|
+
this._percent = this._calculatePercentage(this._value);
|
|
63
|
+
// Since this also modifies the percentage, we need to let the change detection know.
|
|
64
|
+
this._changeDetectorRef.markForCheck();
|
|
65
|
+
}
|
|
66
|
+
/** The minimum value that the slider can have. */
|
|
67
|
+
get min() {
|
|
68
|
+
return this._min;
|
|
69
|
+
}
|
|
70
|
+
set min(v) {
|
|
71
|
+
this._min = coerceNumberProperty(v, this._min);
|
|
72
|
+
// If the value wasn't explicitly set by the user, set it to the min.
|
|
73
|
+
if (this._value === null) {
|
|
74
|
+
this.value = this._min;
|
|
75
|
+
}
|
|
76
|
+
this._percent = this._calculatePercentage(this._value);
|
|
77
|
+
// Since this also modifies the percentage, we need to let the change detection know.
|
|
78
|
+
this._changeDetectorRef.markForCheck();
|
|
79
|
+
}
|
|
80
|
+
/** The values at which the thumb will snap. */
|
|
81
|
+
get step() {
|
|
82
|
+
return this._step;
|
|
83
|
+
}
|
|
84
|
+
set step(v) {
|
|
85
|
+
this._step = coerceNumberProperty(v, this._step);
|
|
86
|
+
if (this._step % 1 !== 0) {
|
|
87
|
+
this._roundToDecimal = this._step.toString().split('.').pop().length;
|
|
88
|
+
}
|
|
89
|
+
// Since this could modify the label, we need to notify the change detection.
|
|
90
|
+
this._changeDetectorRef.markForCheck();
|
|
91
|
+
}
|
|
92
|
+
/** Whether or not to show the thumb label. */
|
|
93
|
+
get thumbLabel() {
|
|
94
|
+
return this._thumbLabel;
|
|
95
|
+
}
|
|
96
|
+
set thumbLabel(value) {
|
|
97
|
+
this._thumbLabel = coerceBooleanProperty(value);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* How often to show ticks. Relative to the step so that a tick always appears on a step.
|
|
101
|
+
* Ex: Tick interval of 4 with a step of 3 will draw a tick every 4 steps (every 12 values).
|
|
102
|
+
*/
|
|
103
|
+
get tickInterval() {
|
|
104
|
+
return this._tickInterval;
|
|
105
|
+
}
|
|
106
|
+
set tickInterval(value) {
|
|
107
|
+
if (value === 'auto') {
|
|
108
|
+
this._tickInterval = 'auto';
|
|
109
|
+
}
|
|
110
|
+
else if (typeof value === 'number' || typeof value === 'string') {
|
|
111
|
+
this._tickInterval = coerceNumberProperty(value, this._tickInterval);
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
this._tickInterval = 0;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/** Value of the slider. */
|
|
118
|
+
get value() {
|
|
119
|
+
// If the value needs to be read and it is still uninitialized, initialize it to the min.
|
|
120
|
+
if (this._value === null) {
|
|
121
|
+
this.value = this._min;
|
|
122
|
+
}
|
|
123
|
+
return this._value;
|
|
124
|
+
}
|
|
125
|
+
set value(v) {
|
|
126
|
+
if (v !== this._value ||
|
|
127
|
+
(v instanceof Array &&
|
|
128
|
+
this._value != null &&
|
|
129
|
+
(v[0] !== this._value[0] || v[1] !== this._value[1]))) {
|
|
130
|
+
let value = null;
|
|
131
|
+
if (v instanceof Array) {
|
|
132
|
+
value = [coerceNumberProperty(v[0]), coerceNumberProperty(v[1])];
|
|
133
|
+
value = [Math.min(value[0], value[1]), Math.max(value[1], value[0])];
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
value = coerceNumberProperty(v);
|
|
137
|
+
}
|
|
138
|
+
// While incrementing by a decimal we can end up with values like 33.300000000000004.
|
|
139
|
+
// Truncate it to ensure that it matches the label and to make it easier to work with.
|
|
140
|
+
if (this._roundToDecimal) {
|
|
141
|
+
if (v instanceof Array) {
|
|
142
|
+
value = [
|
|
143
|
+
parseFloat(value[0].toFixed(this._roundToDecimal)),
|
|
144
|
+
parseFloat(value[1].toFixed(this._roundToDecimal)),
|
|
145
|
+
];
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
value = parseFloat(Number(value).toFixed(this._roundToDecimal));
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
this._value = value;
|
|
152
|
+
this._percent = this._calculatePercentage(this._value);
|
|
153
|
+
// Since this also modifies the percentage, we need to let the change detection know.
|
|
154
|
+
this._changeDetectorRef.markForCheck();
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/** Whether the slider is vertical. */
|
|
158
|
+
get vertical() {
|
|
159
|
+
return this._vertical;
|
|
160
|
+
}
|
|
161
|
+
set vertical(value) {
|
|
162
|
+
this._vertical = coerceBooleanProperty(value);
|
|
163
|
+
}
|
|
164
|
+
/** The value to be used for display purposes. */
|
|
165
|
+
get displayValue() {
|
|
166
|
+
if (this.value == null) {
|
|
167
|
+
return '';
|
|
168
|
+
}
|
|
169
|
+
if (this.displayWith) {
|
|
170
|
+
if (this.value instanceof Array) {
|
|
171
|
+
return this.displayWith(this.value[0]);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
return this.displayWith(this.value);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// Note that this could be improved further by rounding something like 0.999 to 1 or
|
|
178
|
+
// 0.899 to 0.9, however it is very performance sensitive, because it gets called on
|
|
179
|
+
// every change detection cycle.
|
|
180
|
+
if (this.value instanceof Array) {
|
|
181
|
+
if (this._roundToDecimal &&
|
|
182
|
+
this.value &&
|
|
183
|
+
(this.value[0] % 1 !== 0 || this.value[1] % 1 !== 0)) {
|
|
184
|
+
return this.value[0].toFixed(this._roundToDecimal);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
if (this._roundToDecimal && this.value && this.value % 1 !== 0) {
|
|
189
|
+
return this.value.toFixed(this._roundToDecimal);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
if (this.value instanceof Array) {
|
|
193
|
+
return this.value[0] || 0;
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
return this.value || 0;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/** The value to be used for display purposes. */
|
|
200
|
+
get displayValueRight() {
|
|
201
|
+
if (this.value == null) {
|
|
202
|
+
return '';
|
|
203
|
+
}
|
|
204
|
+
if (this.displayWith) {
|
|
205
|
+
return this.displayWith(this.value[1]);
|
|
206
|
+
}
|
|
207
|
+
// Note that this could be improved further by rounding something like 0.999 to 1 or
|
|
208
|
+
// 0.899 to 0.9, however it is very performance sensitive, because it gets called on
|
|
209
|
+
// every change detection cycle.
|
|
210
|
+
if (this._roundToDecimal &&
|
|
211
|
+
this.value &&
|
|
212
|
+
this.value != null &&
|
|
213
|
+
this.value[1] % 1 !== 0) {
|
|
214
|
+
return this.value[1].toFixed(this._roundToDecimal);
|
|
215
|
+
}
|
|
216
|
+
return this.value[1] || 0;
|
|
217
|
+
}
|
|
218
|
+
/** set focus to the host element */
|
|
219
|
+
focus() {
|
|
220
|
+
this._focusHostElement();
|
|
221
|
+
}
|
|
222
|
+
/** blur the host element */
|
|
223
|
+
blur() {
|
|
224
|
+
this._blurHostElement();
|
|
225
|
+
}
|
|
226
|
+
/** The percentage of the slider that coincides with the value. */
|
|
227
|
+
get percent() {
|
|
228
|
+
return this._clamp(this._percent);
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Whether the axis of the slider is inverted.
|
|
232
|
+
* (i.e. whether moving the thumb in the positive x or y direction decreases the slider's
|
|
233
|
+
* value).
|
|
234
|
+
*/
|
|
235
|
+
get _invertAxis() {
|
|
236
|
+
// Standard non-inverted mode for a vertical slider should be dragging the thumb from bottom
|
|
237
|
+
// to top. However from a y-axis standpoint this is inverted.
|
|
238
|
+
return this.vertical ? !this.invert : this.invert;
|
|
239
|
+
}
|
|
240
|
+
/** Whether the slider is at its minimum value. */
|
|
241
|
+
get _isMinValue() {
|
|
242
|
+
if (this.value instanceof Array) {
|
|
243
|
+
return this.percent[0] === 0;
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
return this.percent === 0;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* The amount of space to leave between the slider thumb and the track fill & track background
|
|
251
|
+
* elements.
|
|
252
|
+
*/
|
|
253
|
+
get _thumbGap() {
|
|
254
|
+
if (this.disabled) {
|
|
255
|
+
return DISABLED_THUMB_GAP;
|
|
256
|
+
}
|
|
257
|
+
if (this._isMinValue && !this.thumbLabel) {
|
|
258
|
+
return this._isActive ? MIN_VALUE_ACTIVE_THUMB_GAP : MIN_VALUE_NONACTIVE_THUMB_GAP;
|
|
259
|
+
}
|
|
260
|
+
return 0;
|
|
261
|
+
}
|
|
262
|
+
/** CSS styles for the track background element. */
|
|
263
|
+
get _trackBackgroundStylesLeft() {
|
|
264
|
+
const axis = this.vertical ? 'Y' : 'X';
|
|
265
|
+
let scale = '';
|
|
266
|
+
if (this.percent instanceof Array) {
|
|
267
|
+
scale = this.vertical ? `1, ${this.percent[0]}, 1` : `${this.percent[0]}, 1, 1`;
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
scale = this.vertical ? `1, ${this.percent}, 1` : `${this.percent}, 1, 1`;
|
|
271
|
+
}
|
|
272
|
+
const sign = this._shouldInvertMouseCoords() ? '' : '-';
|
|
273
|
+
return {
|
|
274
|
+
// scale3d avoids some rendering issues in Chrome. See #12071.
|
|
275
|
+
transform: `translate${axis}(${sign}${this._thumbGap}px) scale3d(${scale})`,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
get _trackBackgroundStylesRight() {
|
|
279
|
+
const axis = this.vertical ? 'Y' : 'X';
|
|
280
|
+
let scale = '';
|
|
281
|
+
if (this.percent instanceof Array) {
|
|
282
|
+
scale = this.vertical ? `1, ${1 - this.percent[1]}, 1` : `${1 - this.percent[1]}, 1, 1`;
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
scale = this.vertical ? `1, ${1 - this.percent}, 1` : `${1 - this.percent}, 1, 1`;
|
|
286
|
+
}
|
|
287
|
+
const sign = this._shouldInvertMouseCoords() ? '-' : '';
|
|
288
|
+
return {
|
|
289
|
+
// scale3d avoids some rendering issues in Chrome. See #12071.
|
|
290
|
+
transform: `translate${axis}(${sign}${this._thumbGap}px) scale3d(${scale})`,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
/** CSS styles for the track fill element. */
|
|
294
|
+
get _trackFillStyles() {
|
|
295
|
+
const axis = this.vertical ? 'Y' : 'X';
|
|
296
|
+
let scale = '';
|
|
297
|
+
if (this.percent instanceof Array) {
|
|
298
|
+
scale = this.vertical
|
|
299
|
+
? `1, ${this.percent[1] - this.percent[0]}, 1`
|
|
300
|
+
: `${this.percent[1] - this.percent[0]}, 1, 1`;
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
scale = this.vertical ? `1, ${this.percent}, 1` : `${this.percent}, 1, 1`;
|
|
304
|
+
}
|
|
305
|
+
const invertOffset = this._getDirection() === 'rtl' && !this.vertical ? !this._invertAxis : this._invertAxis;
|
|
306
|
+
let offset = 0;
|
|
307
|
+
if (this.percent instanceof Array) {
|
|
308
|
+
offset = (invertOffset ? 1 - this.percent[1] : this.percent[0]) * 100;
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
offset = 0;
|
|
312
|
+
}
|
|
313
|
+
const sign = this._shouldInvertMouseCoords() ? '' : '-';
|
|
314
|
+
if (this.isRangeSlider()) {
|
|
315
|
+
return {
|
|
316
|
+
// scale3d avoids some rendering issues in Chrome. See #12071.
|
|
317
|
+
transform: `translate${axis}(${offset}%) scale3d(${scale})`,
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
return {
|
|
322
|
+
// scale3d avoids some rendering issues in Chrome. See #12071.
|
|
323
|
+
transform: `translate${axis}(${sign}${this._thumbGap}px) scale3d(${scale})`,
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
/** CSS styles for the ticks container element. */
|
|
328
|
+
get _ticksContainerStyles() {
|
|
329
|
+
const axis = this.vertical ? 'Y' : 'X';
|
|
330
|
+
// For a horizontal slider in RTL languages we push the ticks container off the left edge
|
|
331
|
+
// instead of the right edge to avoid causing a horizontal scrollbar to appear.
|
|
332
|
+
const sign = !this.vertical && this._getDirection() === 'rtl' ? '' : '-';
|
|
333
|
+
const offset = (this._tickIntervalPercent / 2) * 100;
|
|
334
|
+
return {
|
|
335
|
+
transform: `translate${axis}(${sign}${offset}%)`,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
/** CSS styles for the ticks element. */
|
|
339
|
+
get _ticksStyles() {
|
|
340
|
+
const tickSize = this._tickIntervalPercent * 100;
|
|
341
|
+
const backgroundSize = this.vertical ? `2px ${tickSize}%` : `${tickSize}% 2px`;
|
|
342
|
+
const axis = this.vertical ? 'Y' : 'X';
|
|
343
|
+
// Depending on the direction we pushed the ticks container, push the ticks the opposite
|
|
344
|
+
// direction to re-center them but clip off the end edge. In RTL languages we need to flip
|
|
345
|
+
// the ticks 180 degrees so we're really cutting off the end edge abd not the start.
|
|
346
|
+
const sign = !this.vertical && this._getDirection() === 'rtl' ? '-' : '';
|
|
347
|
+
const rotate = !this.vertical && this._getDirection() === 'rtl' ? ' rotate(180deg)' : '';
|
|
348
|
+
const styles = {
|
|
349
|
+
backgroundSize,
|
|
350
|
+
// Without translateZ ticks sometimes jitter as the slider moves on Chrome & Firefox.
|
|
351
|
+
transform: `translateZ(0) translate${axis}(${sign}${tickSize / 2}%)${rotate}`,
|
|
352
|
+
};
|
|
353
|
+
if (this._isMinValue && this._thumbGap) {
|
|
354
|
+
const side = this.vertical
|
|
355
|
+
? this._invertAxis
|
|
356
|
+
? 'Bottom'
|
|
357
|
+
: 'Top'
|
|
358
|
+
: this._invertAxis
|
|
359
|
+
? 'Right'
|
|
360
|
+
: 'Left';
|
|
361
|
+
styles[`padding${side}`] = `${this._thumbGap}px`;
|
|
362
|
+
}
|
|
363
|
+
return styles;
|
|
364
|
+
}
|
|
365
|
+
get _thumbContainerStylesLeft() {
|
|
366
|
+
const axis = this.vertical ? 'Y' : 'X';
|
|
367
|
+
// For a horizontal slider in RTL languages we push the thumb container off the left edge
|
|
368
|
+
// instead of the right edge to avoid causing a horizontal scrollbar to appear.
|
|
369
|
+
const invertOffset = this._getDirection() === 'rtl' && !this.vertical ? !this._invertAxis : this._invertAxis;
|
|
370
|
+
let offset = 0;
|
|
371
|
+
if (this.percent instanceof Array) {
|
|
372
|
+
offset = (invertOffset ? this.percent[0] : 1 - this.percent[0]) * 100;
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
offset = (invertOffset ? this.percent : 1 - this.percent) * 100;
|
|
376
|
+
}
|
|
377
|
+
return {
|
|
378
|
+
transform: `translate${axis}(-${offset}%)`,
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
get _thumbContainerStylesRight() {
|
|
382
|
+
const axis = this.vertical ? 'Y' : 'X';
|
|
383
|
+
// For a horizontal slider in RTL languages we push the thumb container off the left edge
|
|
384
|
+
// instead of the right edge to avoid causing a horizontal scrollbar to appear.
|
|
385
|
+
const invertOffset = this._getDirection() === 'rtl' && !this.vertical ? !this._invertAxis : this._invertAxis;
|
|
386
|
+
let offset = 0;
|
|
387
|
+
if (this.percent instanceof Array) {
|
|
388
|
+
offset = (invertOffset ? this.percent[1] : 1 - this.percent[1]) * 100;
|
|
389
|
+
}
|
|
390
|
+
else {
|
|
391
|
+
offset = (invertOffset ? this.percent : 1 - this.percent) * 100;
|
|
392
|
+
}
|
|
393
|
+
return {
|
|
394
|
+
transform: `translate${axis}(-${offset}%)`,
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Whether mouse events should be converted to a slider position by calculating their distance
|
|
399
|
+
* from the right or bottom edge of the slider as opposed to the top or left.
|
|
400
|
+
*/
|
|
401
|
+
_shouldInvertMouseCoords() {
|
|
402
|
+
return this._getDirection() === 'rtl' && !this.vertical ? !this._invertAxis : this._invertAxis;
|
|
403
|
+
}
|
|
404
|
+
/** The language direction for this slider element. */
|
|
405
|
+
_getDirection() {
|
|
406
|
+
return this._dir && this._dir.value === 'rtl' ? 'rtl' : 'ltr';
|
|
407
|
+
}
|
|
408
|
+
constructor(elementRef, _focusMonitor, _changeDetectorRef, _dir, tabIndex,
|
|
409
|
+
// @breaking-change 7.0.0 `_animationMode` parameter to be made required.
|
|
410
|
+
_animationMode, _ngZone) {
|
|
411
|
+
super(elementRef);
|
|
412
|
+
this._focusMonitor = _focusMonitor;
|
|
413
|
+
this._changeDetectorRef = _changeDetectorRef;
|
|
414
|
+
this._dir = _dir;
|
|
415
|
+
this._animationMode = _animationMode;
|
|
416
|
+
this._ngZone = _ngZone;
|
|
417
|
+
this._invert = false;
|
|
418
|
+
this._max = 100;
|
|
419
|
+
this._min = 0;
|
|
420
|
+
this._step = 1;
|
|
421
|
+
this._thumbLabel = false;
|
|
422
|
+
this._tickInterval = 0;
|
|
423
|
+
this._value = null;
|
|
424
|
+
this._vertical = false;
|
|
425
|
+
/** Event emitted when the slider value has changed. */
|
|
426
|
+
this.change = new EventEmitter();
|
|
427
|
+
/** Event emitted when the slider thumb moves. */
|
|
428
|
+
this.input = new EventEmitter();
|
|
429
|
+
/**
|
|
430
|
+
* Emits when the raw value of the slider changes. This is here primarily
|
|
431
|
+
* to facilitate the two-way binding for the `value` input.
|
|
432
|
+
* @docs-private
|
|
433
|
+
*/
|
|
434
|
+
this.valueChange = new EventEmitter();
|
|
435
|
+
/** onTouch function registered via registerOnTouch (ControlValueAccessor). */
|
|
436
|
+
this.onTouched = () => { };
|
|
437
|
+
this._percent = 0;
|
|
438
|
+
/**
|
|
439
|
+
* Whether or not the thumb is sliding.
|
|
440
|
+
* Used to determine if there should be a transition for the thumb and fill track.
|
|
441
|
+
*/
|
|
442
|
+
this._isSliding = false;
|
|
443
|
+
/**
|
|
444
|
+
* Whether or not the slider is active (clicked or sliding).
|
|
445
|
+
* Used to shrink and grow the thumb as according to the Material Design spec.
|
|
446
|
+
*/
|
|
447
|
+
this._isActive = false;
|
|
448
|
+
/** The size of a tick interval as a percentage of the size of the track. */
|
|
449
|
+
this._tickIntervalPercent = 0;
|
|
450
|
+
/** The dimensions of the slider. */
|
|
451
|
+
this._sliderDimensions = null;
|
|
452
|
+
this._controlValueAccessorChangeFn = () => { };
|
|
453
|
+
/** Subscription to the Directionality change EventEmitter. */
|
|
454
|
+
this._dirChangeSubscription = Subscription.EMPTY;
|
|
455
|
+
/** The slider thumb which is currently used (left or right) */
|
|
456
|
+
this._currentSliderDir = 'l';
|
|
457
|
+
/** Called when the user has put their pointer down on the slider. */
|
|
458
|
+
this._pointerDown = (event) => {
|
|
459
|
+
// Don't do anything if the slider is disabled or the
|
|
460
|
+
// user is using anything other than the main mouse button.
|
|
461
|
+
if (this.disabled || this._isSliding || (!isTouchEvent(event) && event.button !== 0)) {
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
this.calculateInitialSlideDirection(event);
|
|
465
|
+
this._runInsideZone(() => {
|
|
466
|
+
const oldValue = this.value;
|
|
467
|
+
const pointerPosition = getPointerPositionOnPage(event);
|
|
468
|
+
this._isSliding = true;
|
|
469
|
+
event.preventDefault();
|
|
470
|
+
this._focusHostElement();
|
|
471
|
+
this._onMouseenter(); // Simulate mouseenter in case this is a mobile device.
|
|
472
|
+
this._bindGlobalEvents(event);
|
|
473
|
+
this._focusHostElement();
|
|
474
|
+
// TODO:
|
|
475
|
+
// this._updateValueFromPosition(pointerPosition);
|
|
476
|
+
if (this.value instanceof Array) {
|
|
477
|
+
if (this._currentSliderDir === 'l') {
|
|
478
|
+
this._updateValueFromPositionLeft(pointerPosition);
|
|
479
|
+
}
|
|
480
|
+
else if (this._currentSliderDir === 'r') {
|
|
481
|
+
this._updateValueFromPositionRight(pointerPosition);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
else {
|
|
485
|
+
this._updateValueFromPositionLeft(pointerPosition);
|
|
486
|
+
}
|
|
487
|
+
this._valueOnSlideStart = this.value;
|
|
488
|
+
this._pointerPositionOnStart = pointerPosition;
|
|
489
|
+
// Emit a change and input event if the value changed.
|
|
490
|
+
if (oldValue !== this.value) {
|
|
491
|
+
this._emitInputEvent();
|
|
492
|
+
this._emitChangeEvent();
|
|
493
|
+
}
|
|
494
|
+
});
|
|
495
|
+
};
|
|
496
|
+
/**
|
|
497
|
+
* Called when the user has moved their pointer after
|
|
498
|
+
* starting to drag. Bound on the document level.
|
|
499
|
+
*/
|
|
500
|
+
this._pointerMove = (event) => {
|
|
501
|
+
if (this._isSliding) {
|
|
502
|
+
this.calculateInitialSlideDirection(event);
|
|
503
|
+
// Prevent the slide from selecting anything else.
|
|
504
|
+
event.preventDefault();
|
|
505
|
+
const oldValue = this.value;
|
|
506
|
+
// TODO:
|
|
507
|
+
// this._updateValueFromPosition(getPointerPositionOnPage(event));
|
|
508
|
+
const pointerPosition = getPointerPositionOnPage(event);
|
|
509
|
+
if (this._currentSliderDir === 'l') {
|
|
510
|
+
this._updateValueFromPositionLeft(pointerPosition);
|
|
511
|
+
}
|
|
512
|
+
else if (this._currentSliderDir === 'r') {
|
|
513
|
+
this._updateValueFromPositionRight(pointerPosition);
|
|
514
|
+
}
|
|
515
|
+
else {
|
|
516
|
+
if (!this.isRangeSlider()) {
|
|
517
|
+
this._updateValueFromPositionLeft(pointerPosition);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
// Native range elements always emit `input` events when the value changed while sliding.
|
|
521
|
+
if (oldValue !== this.value) {
|
|
522
|
+
this._emitInputEvent();
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
/** Called when the user has lifted their pointer. Bound on the document level. */
|
|
527
|
+
this._pointerUp = (event) => {
|
|
528
|
+
if (this._isSliding) {
|
|
529
|
+
const pointerPositionOnStart = this._pointerPositionOnStart;
|
|
530
|
+
const currentPointerPosition = getPointerPositionOnPage(event);
|
|
531
|
+
event.preventDefault();
|
|
532
|
+
this._removeGlobalEvents();
|
|
533
|
+
this._valueOnSlideStart = this._pointerPositionOnStart = null;
|
|
534
|
+
this._isSliding = false;
|
|
535
|
+
if (this._valueOnSlideStart !== this.value &&
|
|
536
|
+
!this.disabled &&
|
|
537
|
+
pointerPositionOnStart &&
|
|
538
|
+
(pointerPositionOnStart.x !== currentPointerPosition.x ||
|
|
539
|
+
pointerPositionOnStart.y !== currentPointerPosition.y)) {
|
|
540
|
+
this._emitChangeEvent();
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
};
|
|
544
|
+
this.tabIndex = parseInt(tabIndex, 10) || 0;
|
|
545
|
+
this._runOutsizeZone(() => {
|
|
546
|
+
const element = elementRef.nativeElement;
|
|
547
|
+
element.addEventListener('mousedown', this._pointerDown, activeEventOptions);
|
|
548
|
+
element.addEventListener('touchstart', this._pointerDown, activeEventOptions);
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
ngOnInit() {
|
|
552
|
+
this._focusMonitor.monitor(this._elementRef, true).subscribe((origin) => {
|
|
553
|
+
this._isActive = !!origin && origin !== 'keyboard';
|
|
554
|
+
this._changeDetectorRef.detectChanges();
|
|
555
|
+
});
|
|
556
|
+
if (this._dir) {
|
|
557
|
+
this._dirChangeSubscription = this._dir.change.subscribe(() => {
|
|
558
|
+
this._changeDetectorRef.markForCheck();
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
ngOnDestroy() {
|
|
563
|
+
const element = this._elementRef.nativeElement;
|
|
564
|
+
element.removeEventListener('mousedown', this._pointerDown, activeEventOptions);
|
|
565
|
+
element.removeEventListener('touchstart', this._pointerDown, activeEventOptions);
|
|
566
|
+
this._removeGlobalEvents();
|
|
567
|
+
this._focusMonitor.stopMonitoring(this._elementRef);
|
|
568
|
+
this._dirChangeSubscription.unsubscribe();
|
|
569
|
+
}
|
|
570
|
+
_onMouseenter() {
|
|
571
|
+
if (this.disabled) {
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
574
|
+
// We save the dimensions of the slider here so we can use them to update the spacing of the
|
|
575
|
+
// ticks and determine where on the slider click and slide events happen.
|
|
576
|
+
this._sliderDimensions = this._getSliderDimensions();
|
|
577
|
+
this._updateTickIntervalPercent();
|
|
578
|
+
}
|
|
579
|
+
_onClick(event) {
|
|
580
|
+
if (this.disabled) {
|
|
581
|
+
return;
|
|
582
|
+
}
|
|
583
|
+
let oldValue;
|
|
584
|
+
if (this.value instanceof Array) {
|
|
585
|
+
oldValue = [this.value[0], this.value[1]];
|
|
586
|
+
}
|
|
587
|
+
else {
|
|
588
|
+
oldValue = this.value;
|
|
589
|
+
}
|
|
590
|
+
this._isSliding = false;
|
|
591
|
+
this._focusHostElement();
|
|
592
|
+
if (!this._sliderDimensions) {
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
595
|
+
const offset = this.vertical ? this._sliderDimensions.top : this._sliderDimensions.left;
|
|
596
|
+
const size = this.vertical ? this._sliderDimensions.height : this._sliderDimensions.width;
|
|
597
|
+
const posComponent = this.vertical ? event.clientY : event.clientX;
|
|
598
|
+
// The exact value is calculated from the event and used to find the closest snap value.
|
|
599
|
+
let percent = Number(this._clamp((posComponent - offset) / size));
|
|
600
|
+
if (this._shouldInvertMouseCoords()) {
|
|
601
|
+
percent = 1 - percent;
|
|
602
|
+
}
|
|
603
|
+
if (percent <=
|
|
604
|
+
this.percent[0] +
|
|
605
|
+
(this.percent[1] - this.percent[0]) / 2) {
|
|
606
|
+
this._currentSliderDir = 'l';
|
|
607
|
+
}
|
|
608
|
+
else {
|
|
609
|
+
this._currentSliderDir = 'r';
|
|
610
|
+
}
|
|
611
|
+
if (this._currentSliderDir === 'l') {
|
|
612
|
+
this._updateValueFromPositionLeft({ x: event.clientX, y: event.clientY });
|
|
613
|
+
}
|
|
614
|
+
else {
|
|
615
|
+
this._updateValueFromPositionRight({ x: event.clientX, y: event.clientY });
|
|
616
|
+
}
|
|
617
|
+
// Emit a change and input event if the value changed.
|
|
618
|
+
if (this.value instanceof Array) {
|
|
619
|
+
if (oldValue[0] !== this.value[0] ||
|
|
620
|
+
oldValue[1] !== this.value[1]) {
|
|
621
|
+
this._emitInputEvent();
|
|
622
|
+
this._emitChangeEvent();
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
else {
|
|
626
|
+
if (oldValue !== this.value) {
|
|
627
|
+
this._emitInputEvent();
|
|
628
|
+
this._emitChangeEvent();
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
_onFocus() {
|
|
633
|
+
// We save the dimensions of the slider here so we can use them to update the spacing of the
|
|
634
|
+
// ticks and determine where on the slider click and slide events happen.
|
|
635
|
+
this._sliderDimensions = this._getSliderDimensions();
|
|
636
|
+
this._updateTickIntervalPercent();
|
|
637
|
+
}
|
|
638
|
+
_onBlur() {
|
|
639
|
+
this.onTouched();
|
|
640
|
+
}
|
|
641
|
+
_onKeydown(event) {
|
|
642
|
+
if (this.disabled) {
|
|
643
|
+
return;
|
|
644
|
+
}
|
|
645
|
+
let oldValue;
|
|
646
|
+
if (this.value instanceof Array) {
|
|
647
|
+
oldValue = [this.value[0], this.value[1]];
|
|
648
|
+
}
|
|
649
|
+
else {
|
|
650
|
+
oldValue = this.value;
|
|
651
|
+
}
|
|
652
|
+
switch (event.keyCode) {
|
|
653
|
+
case PAGE_UP:
|
|
654
|
+
this._increment(10);
|
|
655
|
+
break;
|
|
656
|
+
case PAGE_DOWN:
|
|
657
|
+
this._increment(-10);
|
|
658
|
+
break;
|
|
659
|
+
case END:
|
|
660
|
+
this.value = this.max;
|
|
661
|
+
break;
|
|
662
|
+
case HOME:
|
|
663
|
+
this.value = this.min;
|
|
664
|
+
break;
|
|
665
|
+
case LEFT_ARROW:
|
|
666
|
+
// NOTE: For a sighted user it would make more sense that when they press an arrow
|
|
667
|
+
// key on an inverted slider the thumb moves in that direction. However for a blind
|
|
668
|
+
// user, nothing about the slider indicates that it is inverted. They will expect
|
|
669
|
+
// left to be decrement, regardless of how it appears on the screen. For speakers
|
|
670
|
+
// ofRTL languages, they probably expect left to mean increment. Therefore we flip
|
|
671
|
+
// the meaning of the side arrow keys for RTL. For inverted sliders we prefer a
|
|
672
|
+
// good a11y experience to having it "look right" for sighted users, therefore we do
|
|
673
|
+
// not swap the meaning.
|
|
674
|
+
this._increment(this._getDirection() === 'rtl' ? 1 : -1);
|
|
675
|
+
break;
|
|
676
|
+
case UP_ARROW:
|
|
677
|
+
this._increment(1);
|
|
678
|
+
break;
|
|
679
|
+
case RIGHT_ARROW:
|
|
680
|
+
// See comment on LEFT_ARROW about the conditions under which we flip the meaning.
|
|
681
|
+
this._increment(this._getDirection() === 'rtl' ? -1 : 1);
|
|
682
|
+
break;
|
|
683
|
+
case DOWN_ARROW:
|
|
684
|
+
this._increment(-1);
|
|
685
|
+
break;
|
|
686
|
+
default:
|
|
687
|
+
// Return if the key is not one that we explicitly handle to avoid calling
|
|
688
|
+
// preventDefault on it.
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
691
|
+
if (this.value instanceof Array) {
|
|
692
|
+
if (oldValue[0] !== this.value[0] ||
|
|
693
|
+
oldValue[1] !== this.value[1]) {
|
|
694
|
+
this._emitInputEvent();
|
|
695
|
+
this._emitChangeEvent();
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
else {
|
|
699
|
+
if (oldValue !== this.value) {
|
|
700
|
+
this._emitInputEvent();
|
|
701
|
+
this._emitChangeEvent();
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
this._isSliding = true;
|
|
705
|
+
event.preventDefault();
|
|
706
|
+
}
|
|
707
|
+
_onKeyup() {
|
|
708
|
+
this._isSliding = false;
|
|
709
|
+
}
|
|
710
|
+
/**
|
|
711
|
+
* Binds our global move and end events. They're bound at the document level and only while
|
|
712
|
+
* dragging so that the user doesn't have to keep their pointer exactly over the slider
|
|
713
|
+
* as they're swiping across the screen.
|
|
714
|
+
*/
|
|
715
|
+
_bindGlobalEvents(triggerEvent) {
|
|
716
|
+
if (typeof document !== 'undefined' && document) {
|
|
717
|
+
const isTouch = isTouchEvent(triggerEvent);
|
|
718
|
+
const moveEventName = isTouch ? 'touchmove' : 'mousemove';
|
|
719
|
+
const endEventName = isTouch ? 'touchend' : 'mouseup';
|
|
720
|
+
document.body.addEventListener(moveEventName, this._pointerMove, activeEventOptions);
|
|
721
|
+
document.body.addEventListener(endEventName, this._pointerUp, activeEventOptions);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
/** Removes any global event listeners that we may have added. */
|
|
725
|
+
_removeGlobalEvents() {
|
|
726
|
+
if (typeof document !== 'undefined' && document) {
|
|
727
|
+
document.body.removeEventListener('mousemove', this._pointerMove, activeEventOptions);
|
|
728
|
+
document.body.removeEventListener('mouseup', this._pointerUp, activeEventOptions);
|
|
729
|
+
document.body.removeEventListener('touchmove', this._pointerMove, activeEventOptions);
|
|
730
|
+
document.body.removeEventListener('touchend', this._pointerUp, activeEventOptions);
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
/** Increments the slider by the given number of steps (negative number decrements). */
|
|
734
|
+
_increment(numSteps) {
|
|
735
|
+
if (this.value instanceof Array) {
|
|
736
|
+
this.value = this._clamp([(this.value[0] || 0) + this.step * numSteps, (this.value[1] || 0) + this.step * numSteps], this.min, this.max);
|
|
737
|
+
}
|
|
738
|
+
else {
|
|
739
|
+
this.value = this._clamp((this.value || 0) + this.step * numSteps, this.min, this.max);
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
/** Calculate the new value from the new physical location. The value will always be snapped. */
|
|
743
|
+
_updateValueFromPosition(pos) {
|
|
744
|
+
if (!this._sliderDimensions) {
|
|
745
|
+
return;
|
|
746
|
+
}
|
|
747
|
+
const offset = this.vertical ? this._sliderDimensions.top : this._sliderDimensions.left;
|
|
748
|
+
const size = this.vertical ? this._sliderDimensions.height : this._sliderDimensions.width;
|
|
749
|
+
const posComponent = this.vertical ? pos.y : pos.x;
|
|
750
|
+
// The exact value is calculated from the event and used to find the closest snap value.
|
|
751
|
+
let percent = this._clamp((posComponent - offset) / size);
|
|
752
|
+
if (this._shouldInvertMouseCoords()) {
|
|
753
|
+
percent = 1 - percent;
|
|
754
|
+
}
|
|
755
|
+
// Since the steps may not divide cleanly into the max value, if the user
|
|
756
|
+
// slid to 0 or 100 percent, we jump to the min/max value. This approach
|
|
757
|
+
// is slightly more intuitive than using `Math.ceil` below, because it
|
|
758
|
+
// follows the user's pointer closer.
|
|
759
|
+
if (percent === 0) {
|
|
760
|
+
this.value = this.min;
|
|
761
|
+
}
|
|
762
|
+
else if (percent === 1) {
|
|
763
|
+
this.value = this.max;
|
|
764
|
+
}
|
|
765
|
+
else {
|
|
766
|
+
const exactValue = this._calculateValue(percent);
|
|
767
|
+
// This calculation finds the closest step by finding the closest
|
|
768
|
+
// whole number divisible by the step relative to the min.
|
|
769
|
+
const closestValue = Math.round((exactValue - this.min) / this.step) * this.step + this.min;
|
|
770
|
+
// The value needs to snap to the min and max.
|
|
771
|
+
this.value = this._clamp(closestValue, this.min, this.max);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
/** Calculate the new value from the new physical location. The value will always be snapped. */
|
|
775
|
+
_updateValueFromPositionLeft(pos) {
|
|
776
|
+
if (!this._sliderDimensions) {
|
|
777
|
+
return;
|
|
778
|
+
}
|
|
779
|
+
const offset = this.vertical ? this._sliderDimensions.top : this._sliderDimensions.left;
|
|
780
|
+
const size = this.vertical ? this._sliderDimensions.height : this._sliderDimensions.width;
|
|
781
|
+
const posComponent = this.vertical ? pos.y : pos.x;
|
|
782
|
+
// The exact value is calculated from the event and used to find the closest snap value.
|
|
783
|
+
let percent = Number(this._clamp((posComponent - offset) / size));
|
|
784
|
+
if (this._shouldInvertMouseCoords()) {
|
|
785
|
+
percent = 1 - percent;
|
|
786
|
+
}
|
|
787
|
+
// Since the steps may not divide cleanly into the max value, if the user
|
|
788
|
+
// slid to 0 or 100 percent, we jump to the min/max value. This approach
|
|
789
|
+
// is slightly more intuitive than using `Math.ceil` below, because it
|
|
790
|
+
// follows the user's pointer closer.
|
|
791
|
+
if (percent === 0) {
|
|
792
|
+
if (this.value instanceof Array) {
|
|
793
|
+
this.value = [this.min, this.value[1]];
|
|
794
|
+
}
|
|
795
|
+
else {
|
|
796
|
+
this.value = this.min;
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
else if (percent === 1) {
|
|
800
|
+
if (this.value instanceof Array) {
|
|
801
|
+
this.value = [this.max, this.value[1]];
|
|
802
|
+
}
|
|
803
|
+
else {
|
|
804
|
+
this.value = this.max;
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
else {
|
|
808
|
+
const exactValue = this._calculateValue(percent);
|
|
809
|
+
// This calculation finds the closest step by finding the closest
|
|
810
|
+
// whole number divisible by the step relative to the min.
|
|
811
|
+
const closestValue = Math.round((Number(exactValue) - this.min) / this.step) * this.step + this.min;
|
|
812
|
+
// The value needs to snap to the min and max.
|
|
813
|
+
if (this.value instanceof Array) {
|
|
814
|
+
this.value = [Number(this._clamp(closestValue, this.min, this.max)), this.value[1]];
|
|
815
|
+
}
|
|
816
|
+
else {
|
|
817
|
+
this.value = this._clamp(closestValue, this.min, this.max);
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
/** Calculate the new value from the new physical location. The value will always be snapped. */
|
|
822
|
+
_updateValueFromPositionRight(pos) {
|
|
823
|
+
if (!this._sliderDimensions) {
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
826
|
+
const offset = this.vertical ? this._sliderDimensions.top : this._sliderDimensions.left;
|
|
827
|
+
const size = this.vertical ? this._sliderDimensions.height : this._sliderDimensions.width;
|
|
828
|
+
const posComponent = this.vertical ? pos.y : pos.x;
|
|
829
|
+
// The exact value is calculated from the event and used to find the closest snap value.
|
|
830
|
+
let percent = Number(this._clamp((posComponent - offset) / size));
|
|
831
|
+
if (this._shouldInvertMouseCoords()) {
|
|
832
|
+
percent = 1 - percent;
|
|
833
|
+
}
|
|
834
|
+
// Since the steps may not divide cleanly into the max value, if the user
|
|
835
|
+
// slid to 0 or 100 percent, we jump to the min/max value. This approach
|
|
836
|
+
// is slightly more intuitive than using `Math.ceil` below, because it
|
|
837
|
+
// follows the user's pointer closer.
|
|
838
|
+
if (percent === 0) {
|
|
839
|
+
if (this.value instanceof Array) {
|
|
840
|
+
this.value = [this.value[0], this.min];
|
|
841
|
+
}
|
|
842
|
+
else {
|
|
843
|
+
this.value = this.min;
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
else if (percent === 1) {
|
|
847
|
+
if (this.value instanceof Array) {
|
|
848
|
+
this.value = [this.value[0], this.max];
|
|
849
|
+
}
|
|
850
|
+
else {
|
|
851
|
+
this.value = this.max;
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
else {
|
|
855
|
+
const exactValue = this._calculateValue(percent);
|
|
856
|
+
// This calculation finds the closest step by finding the closest
|
|
857
|
+
// whole number divisible by the step relative to the min.
|
|
858
|
+
const closestValue = Math.round((Number(exactValue) - this.min) / this.step) * this.step + this.min;
|
|
859
|
+
// The value needs to snap to the min and max.
|
|
860
|
+
if (this.value instanceof Array) {
|
|
861
|
+
this.value = [this.value[0], Number(this._clamp(closestValue, this.min, this.max))];
|
|
862
|
+
}
|
|
863
|
+
else {
|
|
864
|
+
this.value = this._clamp(closestValue, this.min, this.max);
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
/** Emits a change event if the current value is different from the last emitted value. */
|
|
869
|
+
_emitChangeEvent() {
|
|
870
|
+
this._controlValueAccessorChangeFn(this.value);
|
|
871
|
+
this.valueChange.emit(this.value);
|
|
872
|
+
this.change.emit(this._createChangeEvent());
|
|
873
|
+
}
|
|
874
|
+
/** Emits an input event when the current value is different from the last emitted value. */
|
|
875
|
+
_emitInputEvent() {
|
|
876
|
+
this.input.emit(this._createChangeEvent());
|
|
877
|
+
}
|
|
878
|
+
/** Updates the amount of space between ticks as a percentage of the width of the slider. */
|
|
879
|
+
_updateTickIntervalPercent() {
|
|
880
|
+
if (!this.tickInterval || !this._sliderDimensions) {
|
|
881
|
+
return;
|
|
882
|
+
}
|
|
883
|
+
if (this.tickInterval === 'auto') {
|
|
884
|
+
const trackSize = this.vertical
|
|
885
|
+
? this._sliderDimensions.height
|
|
886
|
+
: this._sliderDimensions.width;
|
|
887
|
+
const pixelsPerStep = (trackSize * this.step) / (this.max - this.min);
|
|
888
|
+
const stepsPerTick = Math.ceil(MIN_AUTO_TICK_SEPARATION / pixelsPerStep);
|
|
889
|
+
const pixelsPerTick = stepsPerTick * this.step;
|
|
890
|
+
this._tickIntervalPercent = pixelsPerTick / trackSize;
|
|
891
|
+
}
|
|
892
|
+
else {
|
|
893
|
+
this._tickIntervalPercent = (this.tickInterval * this.step) / (this.max - this.min);
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
/** Creates a slider change object from the specified value. */
|
|
897
|
+
_createChangeEvent(value = this.value) {
|
|
898
|
+
const event = new MtxSliderChange();
|
|
899
|
+
event.source = this;
|
|
900
|
+
event.value = value;
|
|
901
|
+
return event;
|
|
902
|
+
}
|
|
903
|
+
/** Calculates the percentage of the slider that a value is. */
|
|
904
|
+
_calculatePercentage(value) {
|
|
905
|
+
if (value instanceof Array) {
|
|
906
|
+
return [
|
|
907
|
+
((value[0] || 0) - this.min) / (this.max - this.min),
|
|
908
|
+
((value[1] || 0) - this.min) / (this.max - this.min),
|
|
909
|
+
];
|
|
910
|
+
}
|
|
911
|
+
else {
|
|
912
|
+
return ((value || 0) - this.min) / (this.max - this.min);
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
/** Calculates the value a percentage of the slider corresponds to. */
|
|
916
|
+
_calculateValue(percentage) {
|
|
917
|
+
if (percentage instanceof Array) {
|
|
918
|
+
return [
|
|
919
|
+
this.min + percentage[0] * (this.max - this.min),
|
|
920
|
+
this.min + percentage[1] * (this.max - this.min),
|
|
921
|
+
];
|
|
922
|
+
}
|
|
923
|
+
else {
|
|
924
|
+
return this.min + percentage * (this.max - this.min);
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
/** Return a number between two numbers. */
|
|
928
|
+
_clamp(value, min = 0, max = 1) {
|
|
929
|
+
if (value instanceof Array) {
|
|
930
|
+
return [Math.max(min, Math.min(value[0], max)), Math.max(min, Math.min(value[1], max))];
|
|
931
|
+
}
|
|
932
|
+
else {
|
|
933
|
+
return Math.max(min, Math.min(value, max));
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
/**
|
|
937
|
+
* Get the bounding client rect of the slider track element.
|
|
938
|
+
* The track is used rather than the native element to ignore the extra space that the thumb can
|
|
939
|
+
* take up.
|
|
940
|
+
*/
|
|
941
|
+
_getSliderDimensions() {
|
|
942
|
+
return this._sliderWrapper ? this._sliderWrapper.nativeElement.getBoundingClientRect() : null;
|
|
943
|
+
}
|
|
944
|
+
/**
|
|
945
|
+
* Focuses the native element.
|
|
946
|
+
* Currently only used to allow a blur event to fire but will be used with keyboard input later.
|
|
947
|
+
*/
|
|
948
|
+
_focusHostElement() {
|
|
949
|
+
this._elementRef.nativeElement.focus();
|
|
950
|
+
}
|
|
951
|
+
/** Blurs the native element. */
|
|
952
|
+
_blurHostElement() {
|
|
953
|
+
this._elementRef.nativeElement.blur();
|
|
954
|
+
}
|
|
955
|
+
/** Runs a callback outside of the NgZone, if possible. */
|
|
956
|
+
_runOutsizeZone(fn) {
|
|
957
|
+
// @breaking-change 9.0.0 Remove this function once `_ngZone` is a required parameter.
|
|
958
|
+
this._ngZone ? this._ngZone.runOutsideAngular(fn) : fn();
|
|
959
|
+
}
|
|
960
|
+
/** Runs a callback inside of the NgZone, if possible. */
|
|
961
|
+
_runInsideZone(fn) {
|
|
962
|
+
// @breaking-change 9.0.0 Remove this function once `_ngZone` is a required parameter.
|
|
963
|
+
this._ngZone ? this._ngZone.run(fn) : fn();
|
|
964
|
+
}
|
|
965
|
+
/**
|
|
966
|
+
* Sets the model value. Implemented as part of ControlValueAccessor.
|
|
967
|
+
* @param value
|
|
968
|
+
*/
|
|
969
|
+
writeValue(value) {
|
|
970
|
+
this.value = value;
|
|
971
|
+
}
|
|
972
|
+
/**
|
|
973
|
+
* Registers a callback to be triggered when the value has changed.
|
|
974
|
+
* Implemented as part of ControlValueAccessor.
|
|
975
|
+
* @param fn Callback to be registered.
|
|
976
|
+
*/
|
|
977
|
+
registerOnChange(fn) {
|
|
978
|
+
this._controlValueAccessorChangeFn = fn;
|
|
979
|
+
}
|
|
980
|
+
/**
|
|
981
|
+
* Registers a callback to be triggered when the component is touched.
|
|
982
|
+
* Implemented as part of ControlValueAccessor.
|
|
983
|
+
* @param fn Callback to be registered.
|
|
984
|
+
*/
|
|
985
|
+
registerOnTouched(fn) {
|
|
986
|
+
this.onTouched = fn;
|
|
987
|
+
}
|
|
988
|
+
/**
|
|
989
|
+
* Sets whether the component should be disabled.
|
|
990
|
+
* Implemented as part of ControlValueAccessor.
|
|
991
|
+
* @param isDisabled
|
|
992
|
+
*/
|
|
993
|
+
setDisabledState(isDisabled) {
|
|
994
|
+
this.disabled = isDisabled;
|
|
995
|
+
}
|
|
996
|
+
isRangeSlider() {
|
|
997
|
+
return this.value instanceof Array;
|
|
998
|
+
}
|
|
999
|
+
calculateInitialSlideDirection(event) {
|
|
1000
|
+
if (!this._sliderDimensions) {
|
|
1001
|
+
return;
|
|
1002
|
+
}
|
|
1003
|
+
const offset = this.vertical ? this._sliderDimensions.top : this._sliderDimensions.left;
|
|
1004
|
+
const size = this.vertical ? this._sliderDimensions.height : this._sliderDimensions.width;
|
|
1005
|
+
const pointerPosition = getPointerPositionOnPage(event);
|
|
1006
|
+
const posComponent = this.vertical ? pointerPosition.y : pointerPosition.x;
|
|
1007
|
+
// The exact value is calculated from the event and used to find the closest snap value.
|
|
1008
|
+
let percent = Number(this._clamp((posComponent - offset) / size));
|
|
1009
|
+
if (this._shouldInvertMouseCoords()) {
|
|
1010
|
+
percent = 1 - percent;
|
|
1011
|
+
}
|
|
1012
|
+
if (percent <=
|
|
1013
|
+
this.percent[0] +
|
|
1014
|
+
(this.percent[1] - this.percent[0]) / 2) {
|
|
1015
|
+
this._currentSliderDir = 'l';
|
|
1016
|
+
}
|
|
1017
|
+
else {
|
|
1018
|
+
this._currentSliderDir = 'r';
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
/** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.3", ngImport: i0, type: MtxSlider, deps: [{ token: i0.ElementRef }, { token: i1.FocusMonitor }, { token: i0.ChangeDetectorRef }, { token: i2.Directionality, optional: true }, { token: 'tabindex', attribute: true }, { token: ANIMATION_MODULE_TYPE, optional: true }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1022
|
+
/** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.3", type: MtxSlider, selector: "mtx-slider", inputs: { disabled: "disabled", color: "color", tabIndex: "tabIndex", invert: "invert", max: "max", min: "min", step: "step", thumbLabel: "thumbLabel", tickInterval: "tickInterval", value: "value", displayWith: "displayWith", valueText: "valueText", vertical: "vertical" }, outputs: { change: "change", input: "input", valueChange: "valueChange" }, host: { attributes: { "role": "slider" }, listeners: { "focus": "_onFocus()", "blur": "_onBlur()", "click": "_onClick($event)", "keydown": "_onKeydown($event)", "keyup": "_onKeyup()", "mouseenter": "_onMouseenter()", "selectstart": "$event.preventDefault()" }, properties: { "tabIndex": "tabIndex", "attr.aria-disabled": "disabled", "attr.aria-valuemax": "max", "attr.aria-valuemin": "min", "attr.aria-valuenow": "value", "attr.aria-valuetext": "valueText == null ? displayValue : valueText", "attr.aria-orientation": "vertical ? \"vertical\" : \"horizontal\"", "class.mtx-slider-disabled": "disabled", "class.mtx-slider-has-ticks": "tickInterval", "class.mtx-slider-horizontal": "!vertical", "class.mtx-slider-axis-inverted": "_invertAxis", "class.mtx-slider-sliding": "_isSliding", "class.mtx-slider-thumb-label-showing": "thumbLabel", "class.mtx-slider-vertical": "vertical", "class.mtx-slider-min-value": "_isMinValue", "class.mtx-range-slider": "isRangeSlider()", "class.mtx-slider-hide-last-tick": "disabled || _isMinValue && _thumbGap && _invertAxis", "class._mtx-animation-noopable": "_animationMode === \"NoopAnimations\"" }, classAttribute: "mtx-slider mat-focus-indicator" }, providers: [MTX_SLIDER_VALUE_ACCESSOR], viewQueries: [{ propertyName: "_sliderWrapper", first: true, predicate: ["sliderWrapper"], descendants: true }], exportAs: ["mtxSlider"], usesInheritance: true, ngImport: i0, template: "<div class=\"mtx-slider-wrapper\" #sliderWrapper>\n <div class=\"mtx-slider-track-wrapper\">\n <div *ngIf=\"isRangeSlider()\"\n class=\"mtx-slider-track-background mtx-slider-track-background-left\"\n [ngStyle]=\"_trackBackgroundStylesLeft\"></div>\n <div class=\"mtx-slider-track-background mtx-slider-track-background-right\"\n [ngStyle]=\"_trackBackgroundStylesRight\"></div>\n <div class=\"mtx-slider-track-fill\" [ngClass]=\"{'mtx-range-slider-fill': isRangeSlider()}\"\n [ngStyle]=\"_trackFillStyles\"></div>\n </div>\n <div class=\"mtx-slider-ticks-container\" [ngStyle]=\"_ticksContainerStyles\">\n <div class=\"mtx-slider-ticks\" [ngStyle]=\"_ticksStyles\"></div>\n </div>\n <div class=\"mtx-slider-thumb-container\" #leftSlider\n [ngStyle]=\"_thumbContainerStylesLeft\">\n <div class=\"mtx-slider-focus-ring\"></div>\n <div class=\"mtx-slider-thumb left\"></div>\n <div class=\"mtx-slider-thumb-label\">\n <span class=\"mtx-slider-thumb-label-text\">{{displayValue}}</span>\n </div>\n </div>\n <div *ngIf=\"isRangeSlider()\"\n class=\"mtx-slider-thumb-container\" #rightSlider\n [ngStyle]=\"_thumbContainerStylesRight\">\n <div class=\"mtx-slider-focus-ring\"></div>\n <div class=\"mtx-slider-thumb right\"></div>\n <div class=\"mtx-slider-thumb-label\">\n <span class=\"mtx-slider-thumb-label-text\">{{displayValueRight}}</span>\n </div>\n </div>\n</div>\n", styles: [".mtx-slider{display:inline-block;position:relative;box-sizing:border-box;padding:8px;outline:none;vertical-align:middle}.mtx-slider:not(.mtx-slider-disabled):active,.mtx-slider.mtx-slider-sliding:not(.mtx-slider-disabled){cursor:grabbing}.mtx-slider-wrapper{-webkit-print-color-adjust:exact;print-color-adjust:exact;position:absolute}.mtx-slider-track-wrapper{position:absolute;top:0;left:0;overflow:hidden}.mtx-slider-track-fill,.mtx-slider-track-background-left{position:absolute;transform-origin:0 0;transition:transform .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1)}.mtx-slider-track-background-right{position:absolute;transform-origin:100% 100%;transition:transform .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1)}.mtx-slider-ticks-container{position:absolute;left:0;top:0;overflow:hidden}.mtx-slider-ticks{-webkit-background-clip:content-box;background-repeat:repeat;background-clip:content-box;box-sizing:border-box;opacity:0;transition:opacity .4s cubic-bezier(.25,.8,.25,1)}.mtx-slider-thumb-container{position:absolute;z-index:1;transition:transform .4s cubic-bezier(.25,.8,.25,1)}.mtx-slider-focus-ring{position:absolute;width:30px;height:30px;border-radius:50%;transform:scale(0);opacity:0;transition:transform .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1),opacity .4s cubic-bezier(.25,.8,.25,1)}.mtx-slider.cdk-keyboard-focused .mtx-slider-focus-ring,.mtx-slider.cdk-program-focused .mtx-slider-focus-ring{transform:scale(1);opacity:1}.mtx-slider:not(.mtx-slider-disabled,.mtx-slider-sliding) .mtx-slider-thumb-label,.mtx-slider:not(.mtx-slider-disabled,.mtx-slider-sliding) .mtx-slider-thumb{cursor:grab}.mtx-slider-thumb{position:absolute;right:-10px;bottom:-10px;box-sizing:border-box;width:20px;height:20px;border:3px solid transparent;border-radius:50%;transform:scale(.7);transition:transform .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1),border-color .4s cubic-bezier(.25,.8,.25,1)}.mtx-slider-thumb-label{display:none;align-items:center;justify-content:center;position:absolute;width:28px;height:28px;border-radius:50%;transition:transform .4s cubic-bezier(.25,.8,.25,1),border-radius .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1)}.cdk-high-contrast-active .mtx-slider-thumb-label{outline:solid 1px}.mtx-slider-thumb-label-text{z-index:1;opacity:0;transition:opacity .4s cubic-bezier(.25,.8,.25,1)}.mtx-slider-sliding .mtx-slider-track-fill,.mtx-slider-sliding .mtx-slider-track-background-left,.mtx-slider-sliding .mtx-slider-track-background-right,.mtx-slider-sliding .mtx-slider-thumb-container{transition-duration:0ms}.mtx-slider-has-ticks .mtx-slider-wrapper:after{content:\"\";position:absolute;border-width:0;border-style:solid;opacity:0;transition:opacity .4s cubic-bezier(.25,.8,.25,1)}.mtx-slider-has-ticks.cdk-focused:not(.mtx-slider-hide-last-tick) .mtx-slider-wrapper:after,.mtx-slider-has-ticks:hover:not(.mtx-slider-hide-last-tick) .mtx-slider-wrapper:after{opacity:1}.mtx-slider-has-ticks.cdk-focused:not(.mtx-slider-disabled) .mtx-slider-ticks,.mtx-slider-has-ticks:hover:not(.mtx-slider-disabled) .mtx-slider-ticks{opacity:1}.mtx-slider-thumb-label-showing .mtx-slider-focus-ring{display:none}.mtx-slider-thumb-label-showing .mtx-slider-thumb-label{display:flex}.mtx-slider-axis-inverted .mtx-slider-track-fill{transform-origin:100% 100%}.mtx-slider-axis-inverted .mtx-slider-track-fill.mtx-range-slider-fill{transform-origin:0 0}.mtx-slider-axis-inverted .mtx-slider-track-background-left{transform-origin:100% 100%}.mtx-slider-axis-inverted .mtx-slider-track-background-right{transform-origin:0 0}.mtx-slider:not(.mtx-slider-disabled).cdk-focused.mtx-slider-thumb-label-showing .mtx-slider-thumb{transform:scale(0)}.mtx-slider:not(.mtx-slider-disabled).cdk-focused .mtx-slider-thumb-label{border-radius:50% 50% 0}.mtx-slider:not(.mtx-slider-disabled).cdk-focused .mtx-slider-thumb-label-text{opacity:1}.mtx-slider:not(.mtx-slider-disabled).cdk-mouse-focused .mtx-slider-thumb,.mtx-slider:not(.mtx-slider-disabled).cdk-touch-focused .mtx-slider-thumb,.mtx-slider:not(.mtx-slider-disabled).cdk-program-focused .mtx-slider-thumb{border-width:2px;transform:scale(1)}.mtx-slider-disabled .mtx-slider-focus-ring{transform:scale(0);opacity:0}.mtx-slider-disabled .mtx-slider-thumb{border-width:4px;transform:scale(.5)}.mtx-slider-disabled .mtx-slider-thumb-label{display:none}.mtx-slider-horizontal{height:48px;min-width:128px}.mtx-slider-horizontal .mtx-slider-wrapper{height:2px;top:23px;left:8px;right:8px}.mtx-slider-horizontal .mtx-slider-wrapper:after{height:2px;border-left-width:2px;right:0;top:0}.mtx-slider-horizontal .mtx-slider-track-wrapper{height:2px;width:100%}.mtx-slider-horizontal .mtx-slider-track-fill{height:2px;width:100%;transform:scaleX(0)}.mtx-slider-horizontal .mtx-slider-track-background-left,.mtx-slider-horizontal .mtx-slider-track-background-right{height:2px;width:100%;transform:scaleX(1)}.mtx-slider-horizontal .mtx-slider-ticks-container{height:2px;width:100%}.cdk-high-contrast-active .mtx-slider-horizontal .mtx-slider-ticks-container{height:0;outline:solid 2px;top:1px}.mtx-slider-horizontal .mtx-slider-ticks{height:2px;width:100%}.mtx-slider-horizontal .mtx-slider-thumb-container{width:100%;height:0;top:50%}.mtx-slider-horizontal .mtx-slider-focus-ring{top:-15px;right:-15px}.mtx-slider-horizontal .mtx-slider-thumb-label{right:-14px;top:-40px;transform:translateY(26px) scale(.01) rotate(45deg)}.mtx-slider-horizontal .mtx-slider-thumb-label-text{transform:rotate(-45deg)}.mtx-slider-horizontal.cdk-focused .mtx-slider-thumb-label{transform:rotate(45deg)}.cdk-high-contrast-active .mtx-slider-horizontal.cdk-focused .mtx-slider-thumb-label,.cdk-high-contrast-active .mtx-slider-horizontal.cdk-focused .mtx-slider-thumb-label-text{transform:none}.mtx-slider-vertical{width:48px;min-height:128px}.mtx-slider-vertical .mtx-slider-wrapper{width:2px;top:8px;bottom:8px;left:23px}.mtx-slider-vertical .mtx-slider-wrapper:after{width:2px;border-top-width:2px;bottom:0;left:0}.mtx-slider-vertical .mtx-slider-track-wrapper{height:100%;width:2px}.mtx-slider-vertical .mtx-slider-track-fill{height:100%;width:2px;transform:scaleY(0)}.mtx-slider-vertical .mtx-slider-track-background-left,.mtx-slider-vertical .mtx-slider-track-background-right{height:100%;width:2px;transform:scaleY(1)}.mtx-slider-vertical .mtx-slider-ticks-container{width:2px;height:100%}.cdk-high-contrast-active .mtx-slider-vertical .mtx-slider-ticks-container{width:0;outline:solid 2px;left:1px}.mtx-slider-vertical .mtx-slider-focus-ring{bottom:-15px;left:-15px}.mtx-slider-vertical .mtx-slider-ticks{width:2px;height:100%}.mtx-slider-vertical .mtx-slider-thumb-container{height:100%;width:0;left:50%}.mtx-slider-vertical .mtx-slider-thumb{-webkit-backface-visibility:hidden;backface-visibility:hidden}.mtx-slider-vertical .mtx-slider-thumb-label{bottom:-14px;left:-40px;transform:translate(26px) scale(.01) rotate(-45deg)}.mtx-slider-vertical .mtx-slider-thumb-label-text{transform:rotate(45deg)}.mtx-slider-vertical.cdk-focused .mtx-slider-thumb-label{transform:rotate(-45deg)}[dir=rtl] .mtx-slider-wrapper:after{left:0;right:auto}[dir=rtl] .mtx-slider-horizontal .mtx-slider-track-fill:not(.mtx-range-slider-fill){transform-origin:100% 100%}[dir=rtl] .mtx-slider-horizontal .mtx-slider-track-background-left{transform-origin:100% 100%}[dir=rtl] .mtx-slider-horizontal .mtx-slider-track-background-right,[dir=rtl] .mtx-slider-horizontal.mtx-slider-axis-inverted .mtx-slider-track-fill,[dir=rtl] .mtx-slider-horizontal.mtx-slider-axis-inverted .mtx-slider-track-background-left{transform-origin:0 0}[dir=rtl] .mtx-slider-horizontal.mtx-slider-axis-inverted .mtx-slider-track-background-right{transform-origin:100% 100%}.mtx-slider._mtx-animation-noopable .mtx-slider-track-fill,.mtx-slider._mtx-animation-noopable .mtx-slider-track-background-left,.mtx-slider._mtx-animation-noopable .mtx-slider-track-background-right,.mtx-slider._mtx-animation-noopable .mtx-slider-ticks,.mtx-slider._mtx-animation-noopable .mtx-slider-thumb-container,.mtx-slider._mtx-animation-noopable .mtx-slider-focus-ring,.mtx-slider._mtx-animation-noopable .mtx-slider-thumb,.mtx-slider._mtx-animation-noopable .mtx-slider-thumb-label,.mtx-slider._mtx-animation-noopable .mtx-slider-thumb-label-text,.mtx-slider._mtx-animation-noopable .mtx-slider-has-ticks .mtx-slider-wrapper:after{transition:none}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
1023
|
+
}
|
|
1024
|
+
export { MtxSlider };
|
|
1025
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.3", ngImport: i0, type: MtxSlider, decorators: [{
|
|
1026
|
+
type: Component,
|
|
1027
|
+
args: [{ selector: 'mtx-slider', exportAs: 'mtxSlider', providers: [MTX_SLIDER_VALUE_ACCESSOR], host: {
|
|
1028
|
+
'(focus)': '_onFocus()',
|
|
1029
|
+
'(blur)': '_onBlur()',
|
|
1030
|
+
'(click)': '_onClick($event)',
|
|
1031
|
+
'(keydown)': '_onKeydown($event)',
|
|
1032
|
+
'(keyup)': '_onKeyup()',
|
|
1033
|
+
'(mouseenter)': '_onMouseenter()',
|
|
1034
|
+
// On Safari starting to slide temporarily triggers text selection mode which
|
|
1035
|
+
// show the wrong cursor. We prevent it by stopping the `selectstart` event.
|
|
1036
|
+
'(selectstart)': '$event.preventDefault()',
|
|
1037
|
+
'class': 'mtx-slider mat-focus-indicator',
|
|
1038
|
+
'role': 'slider',
|
|
1039
|
+
'[tabIndex]': 'tabIndex',
|
|
1040
|
+
'[attr.aria-disabled]': 'disabled',
|
|
1041
|
+
'[attr.aria-valuemax]': 'max',
|
|
1042
|
+
'[attr.aria-valuemin]': 'min',
|
|
1043
|
+
'[attr.aria-valuenow]': 'value',
|
|
1044
|
+
// NVDA and Jaws appear to announce the `aria-valuenow` by calculating its percentage based
|
|
1045
|
+
// on its value between `aria-valuemin` and `aria-valuemax`. Due to how decimals are handled,
|
|
1046
|
+
// it can cause the slider to read out a very long value like 0.20000068 if the current value
|
|
1047
|
+
// is 0.2 with a min of 0 and max of 1. We work around the issue by setting `aria-valuetext`
|
|
1048
|
+
// to the same value that we set on the slider's thumb which will be truncated.
|
|
1049
|
+
'[attr.aria-valuetext]': 'valueText == null ? displayValue : valueText',
|
|
1050
|
+
'[attr.aria-orientation]': 'vertical ? "vertical" : "horizontal"',
|
|
1051
|
+
'[class.mtx-slider-disabled]': 'disabled',
|
|
1052
|
+
'[class.mtx-slider-has-ticks]': 'tickInterval',
|
|
1053
|
+
'[class.mtx-slider-horizontal]': '!vertical',
|
|
1054
|
+
'[class.mtx-slider-axis-inverted]': '_invertAxis',
|
|
1055
|
+
'[class.mtx-slider-sliding]': '_isSliding',
|
|
1056
|
+
'[class.mtx-slider-thumb-label-showing]': 'thumbLabel',
|
|
1057
|
+
'[class.mtx-slider-vertical]': 'vertical',
|
|
1058
|
+
'[class.mtx-slider-min-value]': '_isMinValue',
|
|
1059
|
+
'[class.mtx-range-slider]': 'isRangeSlider()',
|
|
1060
|
+
'[class.mtx-slider-hide-last-tick]': 'disabled || _isMinValue && _thumbGap && _invertAxis',
|
|
1061
|
+
'[class._mtx-animation-noopable]': '_animationMode === "NoopAnimations"',
|
|
1062
|
+
}, inputs: ['disabled', 'color', 'tabIndex'], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"mtx-slider-wrapper\" #sliderWrapper>\n <div class=\"mtx-slider-track-wrapper\">\n <div *ngIf=\"isRangeSlider()\"\n class=\"mtx-slider-track-background mtx-slider-track-background-left\"\n [ngStyle]=\"_trackBackgroundStylesLeft\"></div>\n <div class=\"mtx-slider-track-background mtx-slider-track-background-right\"\n [ngStyle]=\"_trackBackgroundStylesRight\"></div>\n <div class=\"mtx-slider-track-fill\" [ngClass]=\"{'mtx-range-slider-fill': isRangeSlider()}\"\n [ngStyle]=\"_trackFillStyles\"></div>\n </div>\n <div class=\"mtx-slider-ticks-container\" [ngStyle]=\"_ticksContainerStyles\">\n <div class=\"mtx-slider-ticks\" [ngStyle]=\"_ticksStyles\"></div>\n </div>\n <div class=\"mtx-slider-thumb-container\" #leftSlider\n [ngStyle]=\"_thumbContainerStylesLeft\">\n <div class=\"mtx-slider-focus-ring\"></div>\n <div class=\"mtx-slider-thumb left\"></div>\n <div class=\"mtx-slider-thumb-label\">\n <span class=\"mtx-slider-thumb-label-text\">{{displayValue}}</span>\n </div>\n </div>\n <div *ngIf=\"isRangeSlider()\"\n class=\"mtx-slider-thumb-container\" #rightSlider\n [ngStyle]=\"_thumbContainerStylesRight\">\n <div class=\"mtx-slider-focus-ring\"></div>\n <div class=\"mtx-slider-thumb right\"></div>\n <div class=\"mtx-slider-thumb-label\">\n <span class=\"mtx-slider-thumb-label-text\">{{displayValueRight}}</span>\n </div>\n </div>\n</div>\n", styles: [".mtx-slider{display:inline-block;position:relative;box-sizing:border-box;padding:8px;outline:none;vertical-align:middle}.mtx-slider:not(.mtx-slider-disabled):active,.mtx-slider.mtx-slider-sliding:not(.mtx-slider-disabled){cursor:grabbing}.mtx-slider-wrapper{-webkit-print-color-adjust:exact;print-color-adjust:exact;position:absolute}.mtx-slider-track-wrapper{position:absolute;top:0;left:0;overflow:hidden}.mtx-slider-track-fill,.mtx-slider-track-background-left{position:absolute;transform-origin:0 0;transition:transform .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1)}.mtx-slider-track-background-right{position:absolute;transform-origin:100% 100%;transition:transform .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1)}.mtx-slider-ticks-container{position:absolute;left:0;top:0;overflow:hidden}.mtx-slider-ticks{-webkit-background-clip:content-box;background-repeat:repeat;background-clip:content-box;box-sizing:border-box;opacity:0;transition:opacity .4s cubic-bezier(.25,.8,.25,1)}.mtx-slider-thumb-container{position:absolute;z-index:1;transition:transform .4s cubic-bezier(.25,.8,.25,1)}.mtx-slider-focus-ring{position:absolute;width:30px;height:30px;border-radius:50%;transform:scale(0);opacity:0;transition:transform .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1),opacity .4s cubic-bezier(.25,.8,.25,1)}.mtx-slider.cdk-keyboard-focused .mtx-slider-focus-ring,.mtx-slider.cdk-program-focused .mtx-slider-focus-ring{transform:scale(1);opacity:1}.mtx-slider:not(.mtx-slider-disabled,.mtx-slider-sliding) .mtx-slider-thumb-label,.mtx-slider:not(.mtx-slider-disabled,.mtx-slider-sliding) .mtx-slider-thumb{cursor:grab}.mtx-slider-thumb{position:absolute;right:-10px;bottom:-10px;box-sizing:border-box;width:20px;height:20px;border:3px solid transparent;border-radius:50%;transform:scale(.7);transition:transform .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1),border-color .4s cubic-bezier(.25,.8,.25,1)}.mtx-slider-thumb-label{display:none;align-items:center;justify-content:center;position:absolute;width:28px;height:28px;border-radius:50%;transition:transform .4s cubic-bezier(.25,.8,.25,1),border-radius .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1)}.cdk-high-contrast-active .mtx-slider-thumb-label{outline:solid 1px}.mtx-slider-thumb-label-text{z-index:1;opacity:0;transition:opacity .4s cubic-bezier(.25,.8,.25,1)}.mtx-slider-sliding .mtx-slider-track-fill,.mtx-slider-sliding .mtx-slider-track-background-left,.mtx-slider-sliding .mtx-slider-track-background-right,.mtx-slider-sliding .mtx-slider-thumb-container{transition-duration:0ms}.mtx-slider-has-ticks .mtx-slider-wrapper:after{content:\"\";position:absolute;border-width:0;border-style:solid;opacity:0;transition:opacity .4s cubic-bezier(.25,.8,.25,1)}.mtx-slider-has-ticks.cdk-focused:not(.mtx-slider-hide-last-tick) .mtx-slider-wrapper:after,.mtx-slider-has-ticks:hover:not(.mtx-slider-hide-last-tick) .mtx-slider-wrapper:after{opacity:1}.mtx-slider-has-ticks.cdk-focused:not(.mtx-slider-disabled) .mtx-slider-ticks,.mtx-slider-has-ticks:hover:not(.mtx-slider-disabled) .mtx-slider-ticks{opacity:1}.mtx-slider-thumb-label-showing .mtx-slider-focus-ring{display:none}.mtx-slider-thumb-label-showing .mtx-slider-thumb-label{display:flex}.mtx-slider-axis-inverted .mtx-slider-track-fill{transform-origin:100% 100%}.mtx-slider-axis-inverted .mtx-slider-track-fill.mtx-range-slider-fill{transform-origin:0 0}.mtx-slider-axis-inverted .mtx-slider-track-background-left{transform-origin:100% 100%}.mtx-slider-axis-inverted .mtx-slider-track-background-right{transform-origin:0 0}.mtx-slider:not(.mtx-slider-disabled).cdk-focused.mtx-slider-thumb-label-showing .mtx-slider-thumb{transform:scale(0)}.mtx-slider:not(.mtx-slider-disabled).cdk-focused .mtx-slider-thumb-label{border-radius:50% 50% 0}.mtx-slider:not(.mtx-slider-disabled).cdk-focused .mtx-slider-thumb-label-text{opacity:1}.mtx-slider:not(.mtx-slider-disabled).cdk-mouse-focused .mtx-slider-thumb,.mtx-slider:not(.mtx-slider-disabled).cdk-touch-focused .mtx-slider-thumb,.mtx-slider:not(.mtx-slider-disabled).cdk-program-focused .mtx-slider-thumb{border-width:2px;transform:scale(1)}.mtx-slider-disabled .mtx-slider-focus-ring{transform:scale(0);opacity:0}.mtx-slider-disabled .mtx-slider-thumb{border-width:4px;transform:scale(.5)}.mtx-slider-disabled .mtx-slider-thumb-label{display:none}.mtx-slider-horizontal{height:48px;min-width:128px}.mtx-slider-horizontal .mtx-slider-wrapper{height:2px;top:23px;left:8px;right:8px}.mtx-slider-horizontal .mtx-slider-wrapper:after{height:2px;border-left-width:2px;right:0;top:0}.mtx-slider-horizontal .mtx-slider-track-wrapper{height:2px;width:100%}.mtx-slider-horizontal .mtx-slider-track-fill{height:2px;width:100%;transform:scaleX(0)}.mtx-slider-horizontal .mtx-slider-track-background-left,.mtx-slider-horizontal .mtx-slider-track-background-right{height:2px;width:100%;transform:scaleX(1)}.mtx-slider-horizontal .mtx-slider-ticks-container{height:2px;width:100%}.cdk-high-contrast-active .mtx-slider-horizontal .mtx-slider-ticks-container{height:0;outline:solid 2px;top:1px}.mtx-slider-horizontal .mtx-slider-ticks{height:2px;width:100%}.mtx-slider-horizontal .mtx-slider-thumb-container{width:100%;height:0;top:50%}.mtx-slider-horizontal .mtx-slider-focus-ring{top:-15px;right:-15px}.mtx-slider-horizontal .mtx-slider-thumb-label{right:-14px;top:-40px;transform:translateY(26px) scale(.01) rotate(45deg)}.mtx-slider-horizontal .mtx-slider-thumb-label-text{transform:rotate(-45deg)}.mtx-slider-horizontal.cdk-focused .mtx-slider-thumb-label{transform:rotate(45deg)}.cdk-high-contrast-active .mtx-slider-horizontal.cdk-focused .mtx-slider-thumb-label,.cdk-high-contrast-active .mtx-slider-horizontal.cdk-focused .mtx-slider-thumb-label-text{transform:none}.mtx-slider-vertical{width:48px;min-height:128px}.mtx-slider-vertical .mtx-slider-wrapper{width:2px;top:8px;bottom:8px;left:23px}.mtx-slider-vertical .mtx-slider-wrapper:after{width:2px;border-top-width:2px;bottom:0;left:0}.mtx-slider-vertical .mtx-slider-track-wrapper{height:100%;width:2px}.mtx-slider-vertical .mtx-slider-track-fill{height:100%;width:2px;transform:scaleY(0)}.mtx-slider-vertical .mtx-slider-track-background-left,.mtx-slider-vertical .mtx-slider-track-background-right{height:100%;width:2px;transform:scaleY(1)}.mtx-slider-vertical .mtx-slider-ticks-container{width:2px;height:100%}.cdk-high-contrast-active .mtx-slider-vertical .mtx-slider-ticks-container{width:0;outline:solid 2px;left:1px}.mtx-slider-vertical .mtx-slider-focus-ring{bottom:-15px;left:-15px}.mtx-slider-vertical .mtx-slider-ticks{width:2px;height:100%}.mtx-slider-vertical .mtx-slider-thumb-container{height:100%;width:0;left:50%}.mtx-slider-vertical .mtx-slider-thumb{-webkit-backface-visibility:hidden;backface-visibility:hidden}.mtx-slider-vertical .mtx-slider-thumb-label{bottom:-14px;left:-40px;transform:translate(26px) scale(.01) rotate(-45deg)}.mtx-slider-vertical .mtx-slider-thumb-label-text{transform:rotate(45deg)}.mtx-slider-vertical.cdk-focused .mtx-slider-thumb-label{transform:rotate(-45deg)}[dir=rtl] .mtx-slider-wrapper:after{left:0;right:auto}[dir=rtl] .mtx-slider-horizontal .mtx-slider-track-fill:not(.mtx-range-slider-fill){transform-origin:100% 100%}[dir=rtl] .mtx-slider-horizontal .mtx-slider-track-background-left{transform-origin:100% 100%}[dir=rtl] .mtx-slider-horizontal .mtx-slider-track-background-right,[dir=rtl] .mtx-slider-horizontal.mtx-slider-axis-inverted .mtx-slider-track-fill,[dir=rtl] .mtx-slider-horizontal.mtx-slider-axis-inverted .mtx-slider-track-background-left{transform-origin:0 0}[dir=rtl] .mtx-slider-horizontal.mtx-slider-axis-inverted .mtx-slider-track-background-right{transform-origin:100% 100%}.mtx-slider._mtx-animation-noopable .mtx-slider-track-fill,.mtx-slider._mtx-animation-noopable .mtx-slider-track-background-left,.mtx-slider._mtx-animation-noopable .mtx-slider-track-background-right,.mtx-slider._mtx-animation-noopable .mtx-slider-ticks,.mtx-slider._mtx-animation-noopable .mtx-slider-thumb-container,.mtx-slider._mtx-animation-noopable .mtx-slider-focus-ring,.mtx-slider._mtx-animation-noopable .mtx-slider-thumb,.mtx-slider._mtx-animation-noopable .mtx-slider-thumb-label,.mtx-slider._mtx-animation-noopable .mtx-slider-thumb-label-text,.mtx-slider._mtx-animation-noopable .mtx-slider-has-ticks .mtx-slider-wrapper:after{transition:none}\n"] }]
|
|
1063
|
+
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1.FocusMonitor }, { type: i0.ChangeDetectorRef }, { type: i2.Directionality, decorators: [{
|
|
1064
|
+
type: Optional
|
|
1065
|
+
}] }, { type: undefined, decorators: [{
|
|
1066
|
+
type: Attribute,
|
|
1067
|
+
args: ['tabindex']
|
|
1068
|
+
}] }, { type: undefined, decorators: [{
|
|
1069
|
+
type: Optional
|
|
1070
|
+
}, {
|
|
1071
|
+
type: Inject,
|
|
1072
|
+
args: [ANIMATION_MODULE_TYPE]
|
|
1073
|
+
}] }, { type: i0.NgZone }]; }, propDecorators: { invert: [{
|
|
1074
|
+
type: Input
|
|
1075
|
+
}], max: [{
|
|
1076
|
+
type: Input
|
|
1077
|
+
}], min: [{
|
|
1078
|
+
type: Input
|
|
1079
|
+
}], step: [{
|
|
1080
|
+
type: Input
|
|
1081
|
+
}], thumbLabel: [{
|
|
1082
|
+
type: Input
|
|
1083
|
+
}], tickInterval: [{
|
|
1084
|
+
type: Input
|
|
1085
|
+
}], value: [{
|
|
1086
|
+
type: Input
|
|
1087
|
+
}], displayWith: [{
|
|
1088
|
+
type: Input
|
|
1089
|
+
}], valueText: [{
|
|
1090
|
+
type: Input
|
|
1091
|
+
}], vertical: [{
|
|
1092
|
+
type: Input
|
|
1093
|
+
}], change: [{
|
|
1094
|
+
type: Output
|
|
1095
|
+
}], input: [{
|
|
1096
|
+
type: Output
|
|
1097
|
+
}], valueChange: [{
|
|
1098
|
+
type: Output
|
|
1099
|
+
}], _sliderWrapper: [{
|
|
1100
|
+
type: ViewChild,
|
|
1101
|
+
args: ['sliderWrapper']
|
|
1102
|
+
}] } });
|
|
1103
|
+
/** Returns whether an event is a touch event. */
|
|
1104
|
+
function isTouchEvent(event) {
|
|
1105
|
+
// This function is called for every pixel that the user has dragged so we need it to be
|
|
1106
|
+
// as fast as possible. Since we only bind mouse events and touch events, we can assume
|
|
1107
|
+
// that if the event's name starts with `t`, it's a touch event.
|
|
1108
|
+
return event.type[0] === 't';
|
|
1109
|
+
}
|
|
1110
|
+
/** Gets the coordinates of a touch or mouse event relative to the viewport. */
|
|
1111
|
+
function getPointerPositionOnPage(event) {
|
|
1112
|
+
// `touches` will be empty for start/end events so we have to fall back to `changedTouches`.
|
|
1113
|
+
const point = isTouchEvent(event) ? event.touches[0] || event.changedTouches[0] : event;
|
|
1114
|
+
return { x: point.clientX, y: point.clientY };
|
|
1115
|
+
}
|
|
1116
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xpZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvZXh0ZW5zaW9ucy9zbGlkZXIvc2xpZGVyLnRzIiwiLi4vLi4vLi4vLi4vcHJvamVjdHMvZXh0ZW5zaW9ucy9zbGlkZXIvc2xpZGVyLmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUVMLHFCQUFxQixFQUNyQixvQkFBb0IsR0FFckIsTUFBTSx1QkFBdUIsQ0FBQztBQUMvQixPQUFPLEVBQ0wsVUFBVSxFQUNWLEdBQUcsRUFDSCxJQUFJLEVBQ0osVUFBVSxFQUNWLFNBQVMsRUFDVCxPQUFPLEVBQ1AsV0FBVyxFQUNYLFFBQVEsR0FDVCxNQUFNLHVCQUF1QixDQUFDO0FBQy9CLE9BQU8sRUFBRSwrQkFBK0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3hFLE9BQU8sRUFDTCxTQUFTLEVBQ1QsdUJBQXVCLEVBRXZCLFNBQVMsRUFFVCxZQUFZLEVBQ1osVUFBVSxFQUNWLE1BQU0sRUFDTixLQUFLLEVBSUwsUUFBUSxFQUNSLE1BQU0sRUFDTixTQUFTLEVBQ1QsaUJBQWlCLEdBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6RSxPQUFPLEVBSUwsVUFBVSxFQUNWLGFBQWEsRUFDYixhQUFhLEdBQ2QsTUFBTSx3QkFBd0IsQ0FBQztBQUNoQyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUM3RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDOzs7OztBQUVwQyxNQUFNLGtCQUFrQixHQUFHLCtCQUErQixDQUFDLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7QUFFL0U7OztHQUdHO0FBQ0gsTUFBTSx3QkFBd0IsR0FBRyxFQUFFLENBQUM7QUFFcEMsZ0RBQWdEO0FBQ2hELE1BQU0sa0JBQWtCLEdBQUcs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R0csU0FBUztzQkFBakIsS0FBSztnQkFJRixRQUFRO3NCQURYLEtBQUs7Z0JBVWEsTUFBTTtzQkFBeEIsTUFBTTtnQkFHWSxLQUFLO3NCQUF2QixNQUFNO2dCQU9ZLFdBQVc7c0JBQTdCLE1BQU07Z0JBdVM2QixjQUFjO3NCQUFqRCxTQUFTO3VCQUFDLGVBQWU7O0FBdXFCNUIsaURBQWlEO0FBQ2pELFNBQVMsWUFBWSxDQUFDLEtBQThCO0lBQ2xELHdGQUF3RjtJQUN4Rix1RkFBdUY7SUFDdkYsZ0VBQWdFO0lBQ2hFLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLENBQUM7QUFDL0IsQ0FBQztBQUVELCtFQUErRTtBQUMvRSxTQUFTLHdCQUF3QixDQUFDLEtBQThCO0lBQzlELDRGQUE0RjtJQUM1RixNQUFNLEtBQUssR0FBRyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO0lBQ3hGLE9BQU8sRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO0FBQ2hELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBGb2N1c01vbml0b3IsIEZvY3VzT3JpZ2luIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2ExMXknO1xuaW1wb3J0IHsgRGlyZWN0aW9uYWxpdHkgfSBmcm9tICdAYW5ndWxhci9jZGsvYmlkaSc7XG5pbXBvcnQge1xuICBCb29sZWFuSW5wdXQsXG4gIGNvZXJjZUJvb2xlYW5Qcm9wZXJ0eSxcbiAgY29lcmNlTnVtYmVyUHJvcGVydHksXG4gIE51bWJlcklucHV0LFxufSBmcm9tICdAYW5ndWxhci9jZGsvY29lcmNpb24nO1xuaW1wb3J0IHtcbiAgRE9XTl9BUlJPVyxcbiAgRU5ELFxuICBIT01FLFxuICBMRUZUX0FSUk9XLFxuICBQQUdFX0RPV04sXG4gIFBBR0VfVVAsXG4gIFJJR0hUX0FSUk9XLFxuICBVUF9BUlJPVyxcbn0gZnJvbSAnQGFuZ3VsYXIvY2RrL2tleWNvZGVzJztcbmltcG9ydCB7IG5vcm1hbGl6ZVBhc3NpdmVMaXN0ZW5lck9wdGlvbnMgfSBmcm9tICdAYW5ndWxhci9jZGsvcGxhdGZvcm0nO1xuaW1wb3J0IHtcbiAgQXR0cmlidXRlLFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBmb3J3YXJkUmVmLFxuICBJbmplY3QsXG4gIElucHV0LFxuICBOZ1pvbmUsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPcHRpb25hbCxcbiAgT3V0cHV0LFxuICBWaWV3Q2hpbGQsXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7XG4gIENhbkNvbG9yLFxuICBDYW5EaXNhYmxlLFxuICBIYXNUYWJJbmRleCxcbiAgbWl4aW5Db2xvcixcbiAgbWl4aW5EaXNhYmxlZCxcbiAgbWl4aW5UYWJJbmRleCxcbn0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvY29yZSc7XG5pbXBvcnQgeyBBTklNQVRJT05fTU9EVUxFX1RZUEUgfSBmcm9tICdAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyL2FuaW1hdGlvbnMnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5cbmNvbnN0IGFjdGl2ZUV2ZW50T3B0aW9ucyA9IG5vcm1hbGl6ZVBhc3NpdmVMaXN0ZW5lck9wdGlvbnMoeyBwYXNzaXZlOiBmYWxzZSB9KTtcblxuLyoqXG4gKiBWaXN1YWxseSwgYSAzMHB4IHNlcGFyYXRpb24gYmV0d2VlbiB0aWNrIG1hcmtzIGxvb2tzIGJlc3QuIFRoaXMgaXMgdmVyeSBzdWJqZWN0aXZlIGJ1dCBpdCBpc1xuICogdGhlIGRlZmF1bHQgc2VwYXJhdGlvbiB3ZSBjaG9zZS5cbiAqL1xuY29uc3QgTUlOX0FVVE9fVElDS19TRVBBUkFUSU9OID0gMzA7XG5cbi8qKiBUaGUgdGh1bWIgZ2FwIHNpemUgZm9yIGEgZGlzYWJsZWQgc2xpZGVyLiAqL1xuY29uc3QgRElTQUJMRURfVEhVTUJfR0FQID0gMDtcblxuLyoqIFRoZSB0aHVtYiBnYXAgc2l6ZSBmb3IgYSBub24tYWN0aXZlIHNsaWRlciBhdCBpdHMgbWluaW11bSB2YWx1ZS4gKi9cbmNvbnN0IE1JTl9WQUxVRV9OT05BQ1RJVkVfVEhVTUJfR0FQID0gNztcblxuLyoqIFRoZSB0aHVtYiBnYXAgc2l6ZSBmb3IgYW4gYWN0aXZlIHNsaWRlciBhdCBpdHMgbWluaW11bSB2YWx1ZS4gKi9cbmNvbnN0IE1JTl9WQUxVRV9BQ1RJVkVfVEhVTUJfR0FQID0gMTA7XG5cbi8qKlxuICogUHJvdmlkZXIgRXhwcmVzc2lvbiB0aGF0IGFsbG93cyBtdHgtc2xpZGVyIHRvIHJlZ2lzdGVyIGFzIGEgQ29udHJvbFZhbHVlQWNjZXNzb3IuXG4gKiBUaGlzIGFsbG93cyBpdCB0byBzdXBwb3J0IFsobmdNb2RlbCldIGFuZCBbZm9ybUNvbnRyb2xdLlxuICovXG5leHBvcnQgY29uc3QgTVRYX1NMSURFUl9WQUxVRV9BQ0NFU1NPUjogYW55ID0ge1xuICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gTXR4U2xpZGVyKSxcbiAgbXVsdGk6IHRydWUsXG59O1xuXG4vKiogQSBzaW1wbGUgY2hhbmdlIGV2ZW50IGVtaXR0ZWQgYnkgdGhlIE10eFNsaWRlciBjb21wb25lbnQuICovXG5leHBvcnQgY2xhc3MgTXR4U2xpZGVyQ2hhbmdlIHtcbiAgLyoqIFRoZSBNdHhTbGlkZXIgdGhhdCBjaGFuZ2VkLiAqL1xuICBzb3VyY2UhOiBNdHhTbGlkZXI7XG5cbiAgLyoqIFRoZSBuZXcgdmFsdWUgb2YgdGhlIHNvdXJjZSBzbGlkZXIuICovXG4gIHZhbHVlITogbnVtYmVyIHwgbnVtYmVyW10gfCBudWxsO1xufVxuXG4vLyBCb2lsZXJwbGF0ZSBmb3IgYXBwbHlpbmcgbWl4aW5zIHRvIE10eFNsaWRlci5cbi8qKiBAZG9jcy1wcml2YXRlICovXG5jb25zdCBfTXR4U2xpZGVyQmFzZSA9IG1peGluVGFiSW5kZXgoXG4gIG1peGluQ29sb3IoXG4gICAgbWl4aW5EaXNhYmxlZChcbiAgICAgIGNsYXNzIHtcbiAgICAgICAgY29uc3RydWN0b3IocHVibGljIF9lbGVtZW50UmVmOiBFbGVtZW50UmVmKSB7fVxuICAgICAgfVxuICAgICksXG4gICAgJ2FjY2VudCdcbiAgKVxuKTtcblxuLyoqXG4gKiBBbGxvd3MgdXNlcnMgdG8gc2VsZWN0IGZyb20gYSByYW5nZSBvZiB2YWx1ZXMgYnkgbW92aW5nIHRoZSBzbGlkZXIgdGh1bWIuIEl0IGlzIHNpbWlsYXIgaW5cbiAqIGJlaGF2aW9yIHRvIHRoZSBuYXRpdmUgYDxpbnB1dCB0eXBlPVwicmFuZ2VcIj5gIGVsZW1lbnQuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ210eC1zbGlkZXInLFxuICBleHBvcnRBczogJ210eFNsaWRlcicsXG4gIHByb3ZpZGVyczogW01UWF9TTElERVJfVkFMVUVfQUNDRVNTT1JdLFxuICBob3N0OiB7XG4gICAgJyhmb2N1cyknOiAnX29uRm9jdXMoKScsXG4gICAgJyhibHVyKSc6ICdfb25CbHVyKCknLFxuICAgICcoY2xpY2spJzogJ19vbkNsaWNrKCRldmVudCknLFxuICAgICcoa2V5ZG93biknOiAnX29uS2V5ZG93bigkZXZlbnQpJyxcbiAgICAnKGtleXVwKSc6ICdfb25LZXl1cCgpJyxcbiAgICAnKG1vdXNlZW50ZXIpJzogJ19vbk1vdXNlZW50ZXIoKScsXG5cbiAgICAvLyBPbiBTYWZhcmkgc3RhcnRpbmcgdG8gc2xpZGUgdGVtcG9yYXJpbHkgdHJpZ2dlcnMgdGV4dCBzZWxlY3Rpb24gbW9kZSB3aGljaFxuICAgIC8vIHNob3cgdGhlIHdyb25nIGN1cnNvci4gV2UgcHJldmVudCBpdCBieSBzdG9wcGluZyB0aGUgYHNlbGVjdHN0YXJ0YCBldmVudC5cbiAgICAnKHNlbGVjdHN0YXJ0KSc6ICckZXZlbnQucHJldmVudERlZmF1bHQoKScsXG4gICAgJ2NsYXNzJzogJ210eC1zbGlkZXIgbWF0LWZvY3VzLWluZGljYXRvcicsXG4gICAgJ3JvbGUnOiAnc2xpZGVyJyxcbiAgICAnW3RhYkluZGV4XSc6ICd0YWJJbmRleCcsXG4gICAgJ1thdHRyLmFyaWEtZGlzYWJsZWRdJzogJ2Rpc2FibGVkJyxcbiAgICAnW2F0dHIuYXJpYS12YWx1ZW1heF0nOiAnbWF4JyxcbiAgICAnW2F0dHIuYXJpYS12YWx1ZW1pbl0nOiAnbWluJyxcbiAgICAnW2F0dHIuYXJpYS12YWx1ZW5vd10nOiAndmFsdWUnLFxuXG4gICAgLy8gTlZEQSBhbmQgSmF3cyBhcHBlYXIgdG8gYW5ub3VuY2UgdGhlIGBhcmlhLXZhbHVlbm93YCBieSBjYWxjdWxhdGluZyBpdHMgcGVyY2VudGFnZSBiYXNlZFxuICAgIC8vIG9uIGl0cyB2YWx1ZSBiZXR3ZWVuIGBhcmlhLXZhbHVlbWluYCBhbmQgYGFyaWEtdmFsdWVtYXhgLiBEdWUgdG8gaG93IGRlY2ltYWxzIGFyZSBoYW5kbGVkLFxuICAgIC8vIGl0IGNhbiBjYXVzZSB0aGUgc2xpZGVyIHRvIHJlYWQgb3V0IGEgdmVyeSBsb25nIHZhbHVlIGxpa2UgMC4yMDAwMDA2OCBpZiB0aGUgY3VycmVudCB2YWx1ZVxuICAgIC8vIGlzIDAuMiB3aXRoIGEgbWluIG9mIDAgYW5kIG1heCBvZiAxLiBXZSB3b3JrIGFyb3VuZCB0aGUgaXNzdWUgYnkgc2V0dGluZyBgYXJpYS12YWx1ZXRleHRgXG4gICAgLy8gdG8gdGhlIHNhbWUgdmFsdWUgdGhhdCB3ZSBzZXQgb24gdGhlIHNsaWRlcidzIHRodW1iIHdoaWNoIHdpbGwgYmUgdHJ1bmNhdGVkLlxuICAgICdbYXR0ci5hcmlhLXZhbHVldGV4dF0nOiAndmFsdWVUZXh0ID09IG51bGwgPyBkaXNwbGF5VmFsdWUgOiB2YWx1ZVRleHQnLFxuICAgICdbYXR0ci5hcmlhLW9yaWVudGF0aW9uXSc6ICd2ZXJ0aWNhbCA/IFwidmVydGljYWxcIiA6IFwiaG9yaXpvbnRhbFwiJyxcbiAgICAnW2NsYXNzLm10eC1zbGlkZXItZGlzYWJsZWRdJzogJ2Rpc2FibGVkJyxcbiAgICAnW2NsYXNzLm10eC1zbGlkZXItaGFzLXRpY2tzXSc6ICd0aWNrSW50ZXJ2YWwnLFxuICAgICdbY2xhc3MubXR4LXNsaWRlci1ob3Jpem9udGFsXSc6ICchdmVydGljYWwnLFxuICAgICdbY2xhc3MubXR4LXNsaWRlci1heGlzLWludmVydGVkXSc6ICdfaW52ZXJ0QXhpcycsXG4gICAgJ1tjbGFzcy5tdHgtc2xpZGVyLXNsaWRpbmddJzogJ19pc1NsaWRpbmcnLFxuICAgICdbY2xhc3MubXR4LXNsaWRlci10aHVtYi1sYWJlbC1zaG93aW5nXSc6ICd0aHVtYkxhYmVsJyxcbiAgICAnW2NsYXNzLm10eC1zbGlkZXItdmVydGljYWxdJzogJ3ZlcnRpY2FsJyxcbiAgICAnW2NsYXNzLm10eC1zbGlkZXItbWluLXZhbHVlXSc6ICdfaXNNaW5WYWx1ZScsXG4gICAgJ1tjbGFzcy5tdHgtcmFuZ2Utc2xpZGVyXSc6ICdpc1JhbmdlU2xpZGVyKCknLFxuICAgICdbY2xhc3MubXR4LXNsaWRlci1oaWRlLWxhc3QtdGlja10nOiAnZGlzYWJsZWQgfHwgX2lzTWluVmFsdWUgJiYgX3RodW1iR2FwICYmIF9pbnZlcnRBeGlzJyxcbiAgICAnW2NsYXNzLl9tdHgtYW5pbWF0aW9uLW5vb3BhYmxlXSc6ICdfYW5pbWF0aW9uTW9kZSA9PT0gXCJOb29wQW5pbWF0aW9uc1wiJyxcbiAgfSxcbiAgdGVtcGxhdGVVcmw6ICdzbGlkZXIuaHRtbCcsXG4gIHN0eWxlVXJsczogWydzbGlkZXIuc2NzcyddLFxuICBpbnB1dHM6IFsnZGlzYWJsZWQnLCAnY29sb3InLCAndGFiSW5kZXgnXSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIE10eFNsaWRlclxuICBleHRlbmRzIF9NdHhTbGlkZXJCYXNlXG4gIGltcGxlbWVudHMgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE9uRGVzdHJveSwgQ2FuRGlzYWJsZSwgQ2FuQ29sb3IsIE9uSW5pdCwgSGFzVGFiSW5kZXhcbntcbiAgLyoqIFdoZXRoZXIgdGhlIHNsaWRlciBpcyBpbnZlcnRlZC4gKi9cbiAgQElucHV0KClcbiAgZ2V0IGludmVydCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5faW52ZXJ0O1xuICB9XG4gIHNldCBpbnZlcnQodmFsdWU6IGJvb2xlYW4pIHtcbiAgICB0aGlzLl9pbnZlcnQgPSBjb2VyY2VCb29sZWFuUHJvcGVydHkodmFsdWUpO1xuICB9XG4gIHByaXZhdGUgX2ludmVydCA9IGZhbHNlO1xuXG4gIC8qKiBUaGUgbWF4aW11bSB2YWx1ZSB0aGF0IHRoZSBzbGlkZXIgY2FuIGhhdmUuICovXG4gIEBJbnB1dCgpXG4gIGdldCBtYXgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fbWF4O1xuICB9XG4gIHNldCBtYXgodjogbnVtYmVyKSB7XG4gICAgdGhpcy5fbWF4ID0gY29lcmNlTnVtYmVyUHJvcGVydHkodiwgdGhpcy5fbWF4KTtcbiAgICB0aGlzLl9wZXJjZW50ID0gdGhpcy5fY2FsY3VsYXRlUGVyY2VudGFnZSh0aGlzLl92YWx1ZSk7XG5cbiAgICAvLyBTaW5jZSB0aGlzIGFsc28gbW9kaWZpZXMgdGhlIHBlcmNlbnRhZ2UsIHdlIG5lZWQgdG8gbGV0IHRoZSBjaGFuZ2UgZGV0ZWN0aW9uIGtub3cuXG4gICAgdGhpcy5fY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XG4gIH1cbiAgcHJpdmF0ZSBfbWF4OiBudW1iZXIgPSAxMDA7XG5cbiAgLyoqIFRoZSBtaW5pbXVtIHZhbHVlIHRoYXQgdGhlIHNsaWRlciBjYW4gaGF2ZS4gKi9cbiAgQElucHV0KClcbiAgZ2V0IG1pbigpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl9taW47XG4gIH1cbiAgc2V0IG1pbih2OiBudW1iZXIpIHtcbiAgICB0aGlzLl9taW4gPSBjb2VyY2VOdW1iZXJQcm9wZXJ0eSh2LCB0aGlzLl9taW4pO1xuXG4gICAgLy8gSWYgdGhlIHZhbHVlIHdhc24ndCBleHBsaWNpdGx5IHNldCBieSB0aGUgdXNlciwgc2V0IGl0IHRvIHRoZSBtaW4uXG4gICAgaWYgKHRoaXMuX3ZhbHVlID09PSBudWxsKSB7XG4gICAgICB0aGlzLnZhbHVlID0gdGhpcy5fbWluO1xuICAgIH1cbiAgICB0aGlzLl9wZXJjZW50ID0gdGhpcy5fY2FsY3VsYXRlUGVyY2VudGFnZSh0aGlzLl92YWx1ZSk7XG5cbiAgICAvLyBTaW5jZSB0aGlzIGFsc28gbW9kaWZpZXMgdGhlIHBlcmNlbnRhZ2UsIHdlIG5lZWQgdG8gbGV0IHRoZSBjaGFuZ2UgZGV0ZWN0aW9uIGtub3cuXG4gICAgdGhpcy5fY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XG4gIH1cbiAgcHJpdmF0ZSBfbWluOiBudW1iZXIgPSAwO1xuXG4gIC8qKiBUaGUgdmFsdWVzIGF0IHdoaWNoIHRoZSB0aHVtYiB3aWxsIHNuYXAuICovXG4gIEBJbnB1dCgpXG4gIGdldCBzdGVwKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuX3N0ZXA7XG4gIH1cbiAgc2V0IHN0ZXAodjogbnVtYmVyKSB7XG4gICAgdGhpcy5fc3RlcCA9IGNvZXJjZU51bWJlclByb3BlcnR5KHYsIHRoaXMuX3N0ZXApO1xuXG4gICAgaWYgKHRoaXMuX3N0ZXAgJSAxICE9PSAwKSB7XG4gICAgICB0aGlzLl9yb3VuZFRvRGVjaW1hbCA9IHRoaXMuX3N0ZXAudG9TdHJpbmcoKS5zcGxpdCgnLicpLnBvcCgpIS5sZW5ndGg7XG4gICAgfVxuXG4gICAgLy8gU2luY2UgdGhpcyBjb3VsZCBtb2RpZnkgdGhlIGxhYmVsLCB3ZSBuZWVkIHRvIG5vdGlmeSB0aGUgY2hhbmdlIGRldGVjdGlvbi5cbiAgICB0aGlzLl9jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuICBwcml2YXRlIF9zdGVwOiBudW1iZXIgPSAxO1xuXG4gIC8qKiBXaGV0aGVyIG9yIG5vdCB0byBzaG93IHRoZSB0aHVtYiBsYWJlbC4gKi9cbiAgQElucHV0KClcbiAgZ2V0IHRodW1iTGFiZWwoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX3RodW1iTGFiZWw7XG4gIH1cbiAgc2V0IHRodW1iTGFiZWwodmFsdWU6IGJvb2xlYW4pIHtcbiAgICB0aGlzLl90aHVtYkxhYmVsID0gY29lcmNlQm9vbGVhblByb3BlcnR5KHZhbHVlKTtcbiAgfVxuICBwcml2YXRlIF90aHVtYkxhYmVsOiBib29sZWFuID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIEhvdyBvZnRlbiB0byBzaG93IHRpY2tzLiBSZWxhdGl2ZSB0byB0aGUgc3RlcCBzbyB0aGF0IGEgdGljayBhbHdheXMgYXBwZWFycyBvbiBhIHN0ZXAuXG4gICAqIEV4OiBUaWNrIGludGVydmFsIG9mIDQgd2l0aCBhIHN0ZXAgb2YgMyB3aWxsIGRyYXcgYSB0aWNrIGV2ZXJ5IDQgc3RlcHMgKGV2ZXJ5IDEyIHZhbHVlcykuXG4gICAqL1xuICBASW5wdXQoKVxuICBnZXQgdGlja0ludGVydmFsKCkge1xuICAgIHJldHVybiB0aGlzLl90aWNrSW50ZXJ2YWw7XG4gIH1cbiAgc2V0IHRpY2tJbnRlcnZhbCh2YWx1ZTogJ2F1dG8nIHwgbnVtYmVyKSB7XG4gICAgaWYgKHZhbHVlID09PSAnYXV0bycpIHtcbiAgICAgIHRoaXMuX3RpY2tJbnRlcnZhbCA9ICdhdXRvJztcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgfHwgdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgdGhpcy5fdGlja0ludGVydmFsID0gY29lcmNlTnVtYmVyUHJvcGVydHkodmFsdWUsIHRoaXMuX3RpY2tJbnRlcnZhbCBhcyBudW1iZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl90aWNrSW50ZXJ2YWwgPSAwO1xuICAgIH1cbiAgfVxuICBwcml2YXRlIF90aWNrSW50ZXJ2YWw6ICdhdXRvJyB8IG51bWJlciA9IDA7XG5cbiAgLyoqIFZhbHVlIG9mIHRoZSBzbGlkZXIuICovXG4gIEBJbnB1dCgpXG4gIGdldCB2YWx1ZSgpOiBudW1iZXIgfCBudW1iZXJbXSB8IG51bGwge1xuICAgIC8vIElmIHRoZSB2YWx1ZSBuZWVkcyB0byBiZSByZWFkIGFuZCBpdCBpcyBzdGlsbCB1bmluaXRpYWxpemVkLCBpbml0aWFsaXplIGl0IHRvIHRoZSBtaW4uXG4gICAgaWYgKHRoaXMuX3ZhbHVlID09PSBudWxsKSB7XG4gICAgICB0aGlzLnZhbHVlID0gdGhpcy5fbWluO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fdmFsdWU7XG4gIH1cbiAgc2V0IHZhbHVlKHY6IG51bWJlciB8IG51bWJlcltdIHwgbnVsbCkge1xuICAgIGlmIChcbiAgICAgIHYgIT09IHRoaXMuX3ZhbHVlIHx8XG4gICAgICAodiBpbnN0YW5jZW9mIEFycmF5ICYmXG4gICAgICAgIHRoaXMuX3ZhbHVlICE9IG51bGwgJiZcbiAgICAgICAgKHZbMF0gIT09ICh0aGlzLl92YWx1ZSBhcyBudW1iZXJbXSlbMF0gfHwgdlsxXSAhPT0gKHRoaXMuX3ZhbHVlIGFzIG51bWJlcltdKVsxXSkpXG4gICAgKSB7XG4gICAgICBsZXQgdmFsdWU6IG51bWJlciB8IG51bWJlcltdIHwgbnVsbCA9IG51bGw7XG4gICAgICBpZiAodiBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgIHZhbHVlID0gW2NvZXJjZU51bWJlclByb3BlcnR5KHZbMF0pLCBjb2VyY2VOdW1iZXJQcm9wZXJ0eSh2WzFdKV07XG4gICAgICAgIHZhbHVlID0gW01hdGgubWluKHZhbHVlWzBdLCB2YWx1ZVsxXSksIE1hdGgubWF4KHZhbHVlWzFdLCB2YWx1ZVswXSldO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFsdWUgPSBjb2VyY2VOdW1iZXJQcm9wZXJ0eSh2KTtcbiAgICAgIH1cblxuICAgICAgLy8gV2hpbGUgaW5jcmVtZW50aW5nIGJ5IGEgZGVjaW1hbCB3ZSBjYW4gZW5kIHVwIHdpdGggdmFsdWVzIGxpa2UgMzMuMzAwMDAwMDAwMDAwMDA0LlxuICAgICAgLy8gVHJ1bmNhdGUgaXQgdG8gZW5zdXJlIHRoYXQgaXQgbWF0Y2hlcyB0aGUgbGFiZWwgYW5kIHRvIG1ha2UgaXQgZWFzaWVyIHRvIHdvcmsgd2l0aC5cbiAgICAgIGlmICh0aGlzLl9yb3VuZFRvRGVjaW1hbCkge1xuICAgICAgICBpZiAodiBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgICAgdmFsdWUgPSBbXG4gICAgICAgICAgICBwYXJzZUZsb2F0KCh2YWx1ZSBhcyBudW1iZXJbXSlbMF0udG9GaXhlZCh0aGlzLl9yb3VuZFRvRGVjaW1hbCkpLFxuICAgICAgICAgICAgcGFyc2VGbG9hdCgodmFsdWUgYXMgbnVtYmVyW10pWzFdLnRvRml4ZWQodGhpcy5fcm91bmRUb0RlY2ltYWwpKSxcbiAgICAgICAgICBdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhbHVlID0gcGFyc2VGbG9hdChOdW1iZXIodmFsdWUpLnRvRml4ZWQodGhpcy5fcm91bmRUb0RlY2ltYWwpKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLl92YWx1ZSA9IHZhbHVlO1xuICAgICAgdGhpcy5fcGVyY2VudCA9IHRoaXMuX2NhbGN1bGF0ZVBlcmNlbnRhZ2UodGhpcy5fdmFsdWUpO1xuXG4gICAgICAvLyBTaW5jZSB0aGlzIGFsc28gbW9kaWZpZXMgdGhlIHBlcmNlbnRhZ2UsIHdlIG5lZWQgdG8gbGV0IHRoZSBjaGFuZ2UgZGV0ZWN0aW9uIGtub3cuXG4gICAgICB0aGlzLl9jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG4gIH1cbiAgcHJpdmF0ZSBfdmFsdWU6IG51bWJlciB8IG51bWJlcltdIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqXG4gICAqIEZ1bmN0aW9uIHRoYXQgd2lsbCBiZSB1c2VkIHRvIGZvcm1hdCB0aGUgdmFsdWUgYmVmb3JlIGl0IGlzIGRpc3BsYXllZFxuICAgKiBpbiB0aGUgdGh1bWIgbGFiZWwuIENhbiBiZSB1c2VkIHRvIGZvcm1hdCB2ZXJ5IGxhcmdlIG51bWJlciBpbiBvcmRlclxuICAgKiBmb3IgdGhlbSB0byBmaXQgaW50byB0aGUgc2xpZGVyIHRodW1iLlxuICAgKi9cbiAgQElucHV0KCkgZGlzcGxheVdpdGghOiAodmFsdWU6IG51bWJlciB8IG51bGwpID0+IHN0cmluZyB8IG51bWJlcjtcblxuICAvKiogVGV4dCBjb3JyZXNwb25kaW5nIHRvIHRoZSBzbGlkZXIncyB2YWx1ZS4gVXNlZCBwcmltYXJpbHkgZm9yIGltcHJvdmVkIGFjY2Vzc2liaWxpdHkuICovXG4gIEBJbnB1dCgpIHZhbHVlVGV4dCE6IHN0cmluZztcblxuICAvKiogV2hldGhlciB0aGUgc2xpZGVyIGlzIHZlcnRpY2FsLiAqL1xuICBASW5wdXQoKVxuICBnZXQgdmVydGljYWwoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX3ZlcnRpY2FsO1xuICB9XG4gIHNldCB2ZXJ0aWNhbCh2YWx1ZTogYm9vbGVhbikge1xuICAgIHRoaXMuX3ZlcnRpY2FsID0gY29lcmNlQm9vbGVhblByb3BlcnR5KHZhbHVlKTtcbiAgfVxuICBwcml2YXRlIF92ZXJ0aWNhbCA9IGZhbHNlO1xuXG4gIC8qKiBFdmVudCBlbWl0dGVkIHdoZW4gdGhlIHNsaWRlciB2YWx1ZSBoYXMgY2hhbmdlZC4gKi9cbiAgQE91dHB1dCgpIHJlYWRvbmx5IGNoYW5nZTogRXZlbnRFbWl0dGVyPE10eFNsaWRlckNoYW5nZT4gPSBuZXcgRXZlbnRFbWl0dGVyPE10eFNsaWRlckNoYW5nZT4oKTtcblxuICAvKiogRXZlbnQgZW1pdHRlZCB3aGVuIHRoZSBzbGlkZXIgdGh1bWIgbW92ZXMuICovXG4gIEBPdXRwdXQoKSByZWFkb25seSBpbnB1dDogRXZlbnRFbWl0dGVyPE10eFNsaWRlckNoYW5nZT4gPSBuZXcgRXZlbnRFbWl0dGVyPE10eFNsaWRlckNoYW5nZT4oKTtcblxuICAvKipcbiAgICogRW1pdHMgd2hlbiB0aGUgcmF3IHZhbHVlIG9mIHRoZSBzbGlkZXIgY2hhbmdlcy4gVGhpcyBpcyBoZXJlIHByaW1hcmlseVxuICAgKiB0byBmYWNpbGl0YXRlIHRoZSB0d28td2F5IGJpbmRpbmcgZm9yIHRoZSBgdmFsdWVgIGlucHV0LlxuICAgKiBAZG9jcy1wcml2YXRlXG4gICAqL1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgdmFsdWVDaGFuZ2U6IEV2ZW50RW1pdHRlcjxudW1iZXIgfCBudW1iZXJbXSB8IG51bGw+ID0gbmV3IEV2ZW50RW1pdHRlcjxcbiAgICBudW1iZXIgfCBudW1iZXJbXSB8IG51bGxcbiAgPigpO1xuXG4gIC8qKiBUaGUgdmFsdWUgdG8gYmUgdXNlZCBmb3IgZGlzcGxheSBwdXJwb3Nlcy4gKi9cbiAgZ2V0IGRpc3BsYXlWYWx1ZSgpOiBzdHJpbmcgfCBudW1iZXIge1xuICAgIGlmICh0aGlzLnZhbHVlID09IG51bGwpIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gICAgaWYgKHRoaXMuZGlzcGxheVdpdGgpIHtcbiAgICAgIGlmICh0aGlzLnZhbHVlIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGlzcGxheVdpdGgodGhpcy52YWx1ZVswXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdGhpcy5kaXNwbGF5V2l0aCh0aGlzLnZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBOb3RlIHRoYXQgdGhpcyBjb3VsZCBiZSBpbXByb3ZlZCBmdXJ0aGVyIGJ5IHJvdW5kaW5nIHNvbWV0aGluZyBsaWtlIDAuOTk5IHRvIDEgb3JcbiAgICAvLyAwLjg5OSB0byAwLjksIGhvd2V2ZXIgaXQgaXMgdmVyeSBwZXJmb3JtYW5jZSBzZW5zaXRpdmUsIGJlY2F1c2UgaXQgZ2V0cyBjYWxsZWQgb25cbiAgICAvLyBldmVyeSBjaGFuZ2UgZGV0ZWN0aW9uIGN5Y2xlLlxuICAgIGlmICh0aGlzLnZhbHVlIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgIGlmIChcbiAgICAgICAgdGhpcy5fcm91bmRUb0RlY2ltYWwgJiZcbiAgICAgICAgdGhpcy52YWx1ZSAmJlxuICAgICAgICAodGhpcy52YWx1ZVswXSAlIDEgIT09IDAgfHwgdGhpcy52YWx1ZVsxXSAlIDEgIT09IDApXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVbMF0udG9GaXhlZCh0aGlzLl9yb3VuZFRvRGVjaW1hbCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLl9yb3VuZFRvRGVjaW1hbCAmJiB0aGlzLnZhbHVlICYmIHRoaXMudmFsdWUgJSAxICE9PSAwKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlLnRvRml4ZWQodGhpcy5fcm91bmRUb0RlY2ltYWwpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLnZhbHVlIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgIHJldHVybiB0aGlzLnZhbHVlWzBdIHx8IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLnZhbHVlIHx8IDA7XG4gICAgfVxuICB9XG5cbiAgLyoqIFRoZSB2YWx1ZSB0byBiZSB1c2VkIGZvciBkaXNwbGF5IHB1cnBvc2VzLiAqL1xuICBnZXQgZGlzcGxheVZhbHVlUmlnaHQoKTogc3RyaW5nIHwgbnVtYmVyIHtcbiAgICBpZiAodGhpcy52YWx1ZSA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuICAgIGlmICh0aGlzLmRpc3BsYXlXaXRoKSB7XG4gICAgICByZXR1cm4gdGhpcy5kaXNwbGF5V2l0aCgodGhpcy52YWx1ZSBhcyBudW1iZXJbXSlbMV0pO1xuICAgIH1cblxuICAgIC8vIE5vdGUgdGhhdCB0aGlzIGNvdWxkIGJlIGltcHJvdmVkIGZ1cnRoZXIgYnkgcm91bmRpbmcgc29tZXRoaW5nIGxpa2UgMC45OTkgdG8gMSBvclxuICAgIC8vIDAuODk5IHRvIDAuOSwgaG93ZXZlciBpdCBpcyB2ZXJ5IHBlcmZvcm1hbmNlIHNlbnNpdGl2ZSwgYmVjYXVzZSBpdCBnZXRzIGNhbGxlZCBvblxuICAgIC8vIGV2ZXJ5IGNoYW5nZSBkZXRlY3Rpb24gY3ljbGUuXG4gICAgaWYgKFxuICAgICAgdGhpcy5fcm91bmRUb0RlY2ltYWwgJiZcbiAgICAgIHRoaXMudmFsdWUgJiZcbiAgICAgIHRoaXMudmFsdWUgIT0gbnVsbCAmJlxuICAgICAgKHRoaXMudmFsdWUgYXMgbnVtYmVyW10pWzFdICUgMSAhPT0gMFxuICAgICkge1xuICAgICAgcmV0dXJuICh0aGlzLnZhbHVlIGFzIG51bWJlcltdKVsxXS50b0ZpeGVkKHRoaXMuX3JvdW5kVG9EZWNpbWFsKTtcbiAgICB9XG5cbiAgICByZXR1cm4gKHRoaXMudmFsdWUgYXMgbnVtYmVyW10pWzFdIHx8IDA7XG4gIH1cblxuICAvKiogc2V0IGZvY3VzIHRvIHRoZSBob3N0IGVsZW1lbnQgKi9cbiAgZm9jdXMoKSB7XG4gICAgdGhpcy5fZm9jdXNIb3N0RWxlbWVudCgpO1xuICB9XG5cbiAgLyoqIGJsdXIgdGhlIGhvc3QgZWxlbWVudCAqL1xuICBibHVyKCkge1xuICAgIHRoaXMuX2JsdXJIb3N0RWxlbWVudCgpO1xuICB9XG5cbiAgLyoqIG9uVG91Y2ggZnVuY3Rpb24gcmVnaXN0ZXJlZCB2aWEgcmVnaXN0ZXJPblRvdWNoIChDb250cm9sVmFsdWVBY2Nlc3NvcikuICovXG4gIG9uVG91Y2hlZDogKCkgPT4gYW55ID0gKCkgPT4ge307XG5cbiAgLyoqIFRoZSBwZXJjZW50YWdlIG9mIHRoZSBzbGlkZXIgdGhhdCBjb2luY2lkZXMgd2l0aCB0aGUgdmFsdWUuICovXG4gIGdldCBwZXJjZW50KCk6IG51bWJlciB8IG51bWJlcltdIHtcbiAgICByZXR1cm4gdGhpcy5fY2xhbXAodGhpcy5fcGVyY2VudCk7XG4gIH1cblxuICBwcml2YXRlIF9wZXJjZW50OiBudW1iZXIgfCBudW1iZXJbXSA9IDA7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgb3Igbm90IHRoZSB0aHVtYiBpcyBzbGlkaW5nLlxuICAgKiBVc2VkIHRvIGRldGVybWluZSBpZiB0aGVyZSBzaG91bGQgYmUgYSB0cmFuc2l0aW9uIGZvciB0aGUgdGh1bWIgYW5kIGZpbGwgdHJhY2suXG4gICAqL1xuICBfaXNTbGlkaW5nOiBib29sZWFuID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgb3Igbm90IHRoZSBzbGlkZXIgaXMgYWN0aXZlIChjbGlja2VkIG9yIHNsaWRpbmcpLlxuICAgKiBVc2VkIHRvIHNocmluayBhbmQgZ3JvdyB0aGUgdGh1bWIgYXMgYWNjb3JkaW5nIHRvIHRoZSBNYXRlcmlhbCBEZXNpZ24gc3BlYy5cbiAgICovXG4gIF9pc0FjdGl2ZTogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBheGlzIG9mIHRoZSBzbGlkZXIgaXMgaW52ZXJ0ZWQuXG4gICAqIChpLmUuIHdoZXRoZXIgbW92aW5nIHRoZSB0aHVtYiBpbiB0aGUgcG9zaXRpdmUgeCBvciB5IGRpcmVjdGlvbiBkZWNyZWFzZXMgdGhlIHNsaWRlcidzXG4gICAqICB2YWx1ZSkuXG4gICAqL1xuICBnZXQgX2ludmVydEF4aXMoKSB7XG4gICAgLy8gU3RhbmRhcmQgbm9uLWludmVydGVkIG1vZGUgZm9yIGEgdmVydGljYWwgc2xpZGVyIHNob3VsZCBiZSBkcmFnZ2luZyB0aGUgdGh1bWIgZnJvbSBib3R0b21cbiAgICAvLyB0byB0b3AuIEhvd2V2ZXIgZnJvbSBhIHktYXhpcyBzdGFuZHBvaW50IHRoaXMgaXMgaW52ZXJ0ZWQuXG4gICAgcmV0dXJuIHRoaXMudmVydGljYWwgPyAhdGhpcy5pbnZlcnQgOiB0aGlzLmludmVydDtcbiAgfVxuXG4gIC8qKiBXaGV0aGVyIHRoZSBzbGlkZXIgaXMgYXQgaXRzIG1pbmltdW0gdmFsdWUuICovXG4gIGdldCBfaXNNaW5WYWx1ZSgpIHtcbiAgICBpZiAodGhpcy52YWx1ZSBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICByZXR1cm4gKHRoaXMucGVyY2VudCBhcyBudW1iZXJbXSlbMF0gPT09IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLnBlcmNlbnQgPT09IDA7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBhbW91bnQgb2Ygc3BhY2UgdG8gbGVhdmUgYmV0d2VlbiB0aGUgc2xpZGVyIHRodW1iIGFuZCB0aGUgdHJhY2sgZmlsbCAmIHRyYWNrIGJhY2tncm91bmRcbiAgICogZWxlbWVudHMuXG4gICAqL1xuICBnZXQgX3RodW1iR2FwKCkge1xuICAgIGlmICh0aGlzLmRpc2FibGVkKSB7XG4gICAgICByZXR1cm4gRElTQUJMRURfVEhVTUJfR0FQO1xuICAgIH1cbiAgICBpZiAodGhpcy5faXNNaW5WYWx1ZSAmJiAhdGhpcy50aHVtYkxhYmVsKSB7XG4gICAgICByZXR1cm4gdGhpcy5faXNBY3RpdmUgPyBNSU5fVkFMVUVfQUNUSVZFX1RIVU1CX0dBUCA6IE1JTl9WQUxVRV9OT05BQ1RJVkVfVEhVTUJfR0FQO1xuICAgIH1cbiAgICByZXR1cm4gMDtcbiAgfVxuXG4gIC8qKiBDU1Mgc3R5bGVzIGZvciB0aGUgdHJhY2sgYmFja2dyb3VuZCBlbGVtZW50LiAqL1xuICBnZXQgX3RyYWNrQmFja2dyb3VuZFN0eWxlc0xlZnQoKTogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSB7XG4gICAgY29uc3QgYXhpcyA9IHRoaXMudmVydGljYWwgPyAnWScgOiAnWCc7XG4gICAgbGV0IHNjYWxlOiBzdHJpbmcgPSAnJztcbiAgICBpZiAodGhpcy5wZXJjZW50IGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgIHNjYWxlID0gdGhpcy52ZXJ0aWNhbCA/IGAxLCAke3RoaXMucGVyY2VudFswXX0sIDFgIDogYCR7dGhpcy5wZXJjZW50WzBdfSwgMSwgMWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNjYWxlID0gdGhpcy52ZXJ0aWNhbCA/IGAxLCAke3RoaXMucGVyY2VudH0sIDFgIDogYCR7dGhpcy5wZXJjZW50fSwgMSwgMWA7XG4gICAgfVxuICAgIGNvbnN0IHNpZ24gPSB0aGlzLl9zaG91bGRJbnZlcnRNb3VzZUNvb3JkcygpID8gJycgOiAnLSc7XG5cbiAgICByZXR1cm4ge1xuICAgICAgLy8gc2NhbGUzZCBhdm9pZHMgc29tZSByZW5kZXJpbmcgaXNzdWVzIGluIENocm9tZS4gU2VlICMxMjA3MS5cbiAgICAgIHRyYW5zZm9ybTogYHRyYW5zbGF0ZSR7YXhpc30oJHtzaWdufSR7dGhpcy5fdGh1bWJHYXB9cHgpIHNjYWxlM2QoJHtzY2FsZX0pYCxcbiAgICB9O1xuICB9XG5cbiAgZ2V0IF90cmFja0JhY2tncm91bmRTdHlsZXNSaWdodCgpOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9IHtcbiAgICBjb25zdCBheGlzID0gdGhpcy52ZXJ0aWNhbCA/ICdZJyA6ICdYJztcbiAgICBsZXQgc2NhbGU6IHN0cmluZyA9ICcnO1xuICAgIGlmICh0aGlzLnBlcmNlbnQgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgc2NhbGUgPSB0aGlzLnZlcnRpY2FsID8gYDEsICR7MSAtIHRoaXMucGVyY2VudFsxXX0sIDFgIDogYCR7MSAtIHRoaXMucGVyY2VudFsxXX0sIDEsIDFgO1xuICAgIH0gZWxzZSB7XG4gICAgICBzY2FsZSA9IHRoaXMudmVydGljYWwgPyBgMSwgJHsxIC0gdGhpcy5wZXJjZW50fSwgMWAgOiBgJHsxIC0gdGhpcy5wZXJjZW50fSwgMSwgMWA7XG4gICAgfVxuICAgIGNvbnN0IHNpZ24gPSB0aGlzLl9zaG91bGRJbnZlcnRNb3VzZUNvb3JkcygpID8gJy0nIDogJyc7XG4gICAgcmV0dXJuIHtcbiAgICAgIC8vIHNjYWxlM2QgYXZvaWRzIHNvbWUgcmVuZGVyaW5nIGlzc3VlcyBpbiBDaHJvbWUuIFNlZSAjMTIwNzEuXG4gICAgICB0cmFuc2Zvcm06IGB0cmFuc2xhdGUke2F4aXN9KCR7c2lnbn0ke3RoaXMuX3RodW1iR2FwfXB4KSBzY2FsZTNkKCR7c2NhbGV9KWAsXG4gICAgfTtcbiAgfVxuXG4gIC8qKiBDU1Mgc3R5bGVzIGZvciB0aGUgdHJhY2sgZmlsbCBlbGVtZW50LiAqL1xuICBnZXQgX3RyYWNrRmlsbFN0eWxlcygpOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9IHtcbiAgICBjb25zdCBheGlzID0gdGhpcy52ZXJ0aWNhbCA/ICdZJyA6ICdYJztcbiAgICBsZXQgc2NhbGU6IHN0cmluZyA9ICcnO1xuICAgIGlmICh0aGlzLnBlcmNlbnQgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgc2NhbGUgPSB0aGlzLnZlcnRpY2FsXG4gICAgICAgID8gYDEsICR7dGhpcy5wZXJjZW50WzFdIC0gdGhpcy5wZXJjZW50WzBdfSwgMWBcbiAgICAgICAgOiBgJHt0aGlzLnBlcmNlbnRbMV0gLSB0aGlzLnBlcmNlbnRbMF19LCAxLCAxYDtcbiAgICB9IGVsc2Uge1xuICAgICAgc2NhbGUgPSB0aGlzLnZlcnRpY2FsID8gYDEsICR7dGhpcy5wZXJjZW50fSwgMWAgOiBgJHt0aGlzLnBlcmNlbnR9LCAxLCAxYDtcbiAgICB9XG5cbiAgICBjb25zdCBpbnZlcnRPZmZzZXQgPVxuICAgICAgdGhpcy5fZ2V0RGlyZWN0aW9uKCkgPT09ICdydGwnICYmICF0aGlzLnZlcnRpY2FsID8gIXRoaXMuX2ludmVydEF4aXMgOiB0aGlzLl9pbnZlcnRBeGlzO1xuICAgIGxldCBvZmZzZXQ6IG51bWJlciA9IDA7XG4gICAgaWYgKHRoaXMucGVyY2VudCBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICBvZmZzZXQgPSAoaW52ZXJ0T2Zmc2V0ID8gMSAtIHRoaXMucGVyY2VudFsxXSA6IHRoaXMucGVyY2VudFswXSkgKiAxMDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9mZnNldCA9IDA7XG4gICAgfVxuICAgIGNvbnN0IHNpZ24gPSB0aGlzLl9zaG91bGRJbnZlcnRNb3VzZUNvb3JkcygpID8gJycgOiAnLSc7XG5cbiAgICBpZiAodGhpcy5pc1JhbmdlU2xpZGVyKCkpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC8vIHNjYWxlM2QgYXZvaWRzIHNvbWUgcmVuZGVyaW5nIGlzc3VlcyBpbiBDaHJvbWUuIFNlZSAjMTIwNzEuXG4gICAgICAgIHRyYW5zZm9ybTogYHRyYW5zbGF0ZSR7YXhpc30oJHtvZmZzZXR9JSkgc2NhbGUzZCgke3NjYWxlfSlgLFxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLy8gc2NhbGUzZCBhdm9pZHMgc29tZSByZW5kZXJpbmcgaXNzdWVzIGluIENocm9tZS4gU2VlICMxMjA3MS5cbiAgICAgICAgdHJhbnNmb3JtOiBgdHJhbnNsYXRlJHtheGlzfSgke3NpZ259JHt0aGlzLl90aHVtYkdhcH1weCkgc2NhbGUzZCgke3NjYWxlfSlgLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICAvKiogQ1NTIHN0eWxlcyBmb3IgdGhlIHRpY2tzIGNvbnRhaW5lciBlbGVtZW50LiAqL1xuICBnZXQgX3RpY2tzQ29udGFpbmVyU3R5bGVzKCk6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0ge1xuICAgIGNvbnN0IGF4aXMgPSB0aGlzLnZlcnRpY2FsID8gJ1knIDogJ1gnO1xuICAgIC8vIEZvciBhIGhvcml6b250YWwgc2xpZGVyIGluIFJUTCBsYW5ndWFnZXMgd2UgcHVzaCB0aGUgdGlja3MgY29udGFpbmVyIG9mZiB0aGUgbGVmdCBlZGdlXG4gICAgLy8gaW5zdGVhZCBvZiB0aGUgcmlnaHQgZWRnZSB0byBhdm9pZCBjYXVzaW5nIGEgaG9yaXpvbnRhbCBzY3JvbGxiYXIgdG8gYXBwZWFyLlxuICAgIGNvbnN0IHNpZ24gPSAhdGhpcy52ZXJ0aWNhbCAmJiB0aGlzLl9nZXREaXJlY3Rpb24oKSA9PT0gJ3J0bCcgPyAnJyA6ICctJztcbiAgICBjb25zdCBvZmZzZXQgPSAodGhpcy5fdGlja0ludGVydmFsUGVyY2VudCAvIDIpICogMTAwO1xuICAgIHJldHVybiB7XG4gICAgICB0cmFuc2Zvcm06IGB0cmFuc2xhdGUke2F4aXN9KCR7c2lnbn0ke29mZnNldH0lKWAsXG4gICAgfTtcbiAgfVxuXG4gIC8qKiBDU1Mgc3R5bGVzIGZvciB0aGUgdGlja3MgZWxlbWVudC4gKi9cbiAgZ2V0IF90aWNrc1N0eWxlcygpOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9IHtcbiAgICBjb25zdCB0aWNrU2l6ZSA9IHRoaXMuX3RpY2tJbnRlcnZhbFBlcmNlbnQgKiAxMDA7XG4gICAgY29uc3QgYmFja2dyb3VuZFNpemUgPSB0aGlzLnZlcnRpY2FsID8gYDJweCAke3RpY2tTaXplfSVgIDogYCR7dGlja1NpemV9JSAycHhgO1xuICAgIGNvbnN0IGF4aXMgPSB0aGlzLnZlcnRpY2FsID8gJ1knIDogJ1gnO1xuICAgIC8vIERlcGVuZGluZyBvbiB0aGUgZGlyZWN0aW9uIHdlIHB1c2hlZCB0aGUgdGlja3MgY29udGFpbmVyLCBwdXNoIHRoZSB0aWNrcyB0aGUgb3Bwb3NpdGVcbiAgICAvLyBkaXJlY3Rpb24gdG8gcmUtY2VudGVyIHRoZW0gYnV0IGNsaXAgb2ZmIHRoZSBlbmQgZWRnZS4gSW4gUlRMIGxhbmd1YWdlcyB3ZSBuZWVkIHRvIGZsaXBcbiAgICAvLyB0aGUgdGlja3MgMTgwIGRlZ3JlZXMgc28gd2UncmUgcmVhbGx5IGN1dHRpbmcgb2ZmIHRoZSBlbmQgZWRnZSBhYmQgbm90IHRoZSBzdGFydC5cbiAgICBjb25zdCBzaWduID0gIXRoaXMudmVydGljYWwgJiYgdGhpcy5fZ2V0RGlyZWN0aW9uKCkgPT09ICdydGwnID8gJy0nIDogJyc7XG4gICAgY29uc3Qgcm90YXRlID0gIXRoaXMudmVydGljYWwgJiYgdGhpcy5fZ2V0RGlyZWN0aW9uKCkgPT09ICdydGwnID8gJyByb3RhdGUoMTgwZGVnKScgOiAnJztcbiAgICBjb25zdCBzdHlsZXM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7XG4gICAgICBiYWNrZ3JvdW5kU2l6ZSxcbiAgICAgIC8vIFdpdGhvdXQgdHJhbnNsYXRlWiB0aWNrcyBzb21ldGltZXMgaml0dGVyIGFzIHRoZSBzbGlkZXIgbW92ZXMgb24gQ2hyb21lICYgRmlyZWZveC5cbiAgICAgIHRyYW5zZm9ybTogYHRyYW5zbGF0ZVooMCkgdHJhbnNsYXRlJHtheGlzfSgke3NpZ259JHt0aWNrU2l6ZSAvIDJ9JSkke3JvdGF0ZX1gLFxuICAgIH07XG5cbiAgICBpZiAodGhpcy5faXNNaW5WYWx1ZSAmJiB0aGlzLl90aHVtYkdhcCkge1xuICAgICAgY29uc3Qgc2lkZSA9IHRoaXMudmVydGljYWxcbiAgICAgICAgPyB0aGlzLl9pbnZlcnRBeGlzXG4gICAgICAgICAgPyAnQm90dG9tJ1xuICAgICAgICAgIDogJ1RvcCdcbiAgICAgICAgOiB0aGlzLl9pbnZlcnRBeGlzXG4gICAgICAgID8gJ1JpZ2h0J1xuICAgICAgICA6ICdMZWZ0JztcbiAgICAgIHN0eWxlc1tgcGFkZGluZyR7c2lkZX1gXSA9IGAke3RoaXMuX3RodW1iR2FwfXB4YDtcbiAgICB9XG5cbiAgICByZXR1cm4gc3R5bGVzO1xuICB9XG5cbiAgZ2V0IF90aHVtYkNvbnRhaW5lclN0eWxlc0xlZnQoKTogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSB7XG4gICAgY29uc3QgYXhpcyA9IHRoaXMudmVydGljYWwgPyAnWScgOiAnWCc7XG4gICAgLy8gRm9yIGEgaG9yaXpvbnRhbCBzbGlkZXIgaW4gUlRMIGxhbmd1YWdlcyB3ZSBwdXNoIHRoZSB0aHVtYiBjb250YWluZXIgb2ZmIHRoZSBsZWZ0IGVkZ2VcbiAgICAvLyBpbnN0ZWFkIG9mIHRoZSByaWdodCBlZGdlIHRvIGF2b2lkIGNhdXNpbmcgYSBob3Jpem9udGFsIHNjcm9sbGJhciB0byBhcHBlYXIuXG4gICAgY29uc3QgaW52ZXJ0T2Zmc2V0ID1cbiAgICAgIHRoaXMuX2dldERpcmVjdGlvbigpID09PSAncnRsJyAmJiAhdGhpcy52ZXJ0aWNhbCA/ICF0aGlzLl9pbnZlcnRBeGlzIDogdGhpcy5faW52ZXJ0QXhpcztcbiAgICBsZXQgb2Zmc2V0OiBudW1iZXIgPSAwO1xuICAgIGlmICh0aGlzLnBlcmNlbnQgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgb2Zmc2V0ID0gKGludmVydE9mZnNldCA/IHRoaXMucGVyY2VudFswXSA6IDEgLSB0aGlzLnBlcmNlbnRbMF0pICogMTAwO1xuICAgIH0gZWxzZSB7XG4gICAgICBvZmZzZXQgPSAoaW52ZXJ0T2Zmc2V0ID8gdGhpcy5wZXJjZW50IDogMSAtIHRoaXMucGVyY2VudCkgKiAxMDA7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICB0cmFuc2Zvcm06IGB0cmFuc2xhdGUke2F4aXN9KC0ke29mZnNldH0lKWAsXG4gICAgfTtcbiAgfVxuXG4gIGdldCBfdGh1bWJDb250YWluZXJTdHlsZXNSaWdodCgpOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9IHtcbiAgICBjb25zdCBheGlzID0gdGhpcy52ZXJ0aWNhbCA/ICdZJyA6ICdYJztcbiAgICAvLyBGb3IgYSBob3Jpem9udGFsIHNsaWRlciBpbiBSVEwgbGFuZ3VhZ2VzIHdlIHB1c2ggdGhlIHRodW1iIGNvbnRhaW5lciBvZmYgdGhlIGxlZnQgZWRnZVxuICAgIC8vIGluc3RlYWQgb2YgdGhlIHJpZ2h0IGVkZ2UgdG8gYXZvaWQgY2F1c2luZyBhIGhvcml6b250YWwgc2Nyb2xsYmFyIHRvIGFwcGVhci5cbiAgICBjb25zdCBpbnZlcnRPZmZzZXQgPVxuICAgICAgdGhpcy5fZ2V0RGlyZWN0aW9uKCkgPT09ICdydGwnICYmICF0aGlzLnZlcnRpY2FsID8gIXRoaXMuX2ludmVydEF4aXMgOiB0aGlzLl9pbnZlcnRBeGlzO1xuICAgIGxldCBvZmZzZXQ6IG51bWJlciA9IDA7XG4gICAgaWYgKHRoaXMucGVyY2VudCBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICBvZmZzZXQgPSAoaW52ZXJ0T2Zmc2V0ID8gdGhpcy5wZXJjZW50WzFdIDogMSAtIHRoaXMucGVyY2VudFsxXSkgKiAxMDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9mZnNldCA9IChpbnZlcnRPZmZzZXQgPyB0aGlzLnBlcmNlbnQgOiAxIC0gdGhpcy5wZXJjZW50KSAqIDEwMDtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHRyYW5zZm9ybTogYHRyYW5zbGF0ZSR7YXhpc30oLSR7b2Zmc2V0fSUpYCxcbiAgICB9O1xuICB9XG5cbiAgLyoqIFRoZSBzaXplIG9mIGEgdGljayBpbnRlcnZhbCBhcyBhIHBlcmNlbnRhZ2Ugb2YgdGhlIHNpemUgb2YgdGhlIHRyYWNrLiAqL1xuICBwcml2YXRlIF90aWNrSW50ZXJ2YWxQZXJjZW50OiBudW1iZXIgPSAwO1xuXG4gIC8qKiBUaGUgZGltZW5zaW9ucyBvZiB0aGUgc2xpZGVyLiAqL1xuICBwcml2YXRlIF9zbGlkZXJEaW1lbnNpb25zOiBDbGllbnRSZWN0IHwgbnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSBfY29udHJvbFZhbHVlQWNjZXNzb3JDaGFuZ2VGbjogKHZhbHVlOiBhbnkpID0+IHZvaWQgPSAoKSA9PiB7fTtcblxuICAvKiogRGVjaW1hbCBwbGFjZXMgdG8gcm91bmQgdG8sIGJhc2VkIG9uIHRoZSBzdGVwIGFtb3VudC4gKi9cbiAgcHJpdmF0ZSBfcm91bmRUb0RlY2ltYWwhOiBudW1iZXI7XG5cbiAgLyoqIFN1YnNjcmlwdGlvbiB0byB0aGUgRGlyZWN0aW9uYWxpdHkgY2hhbmdlIEV2ZW50RW1pdHRlci4gKi9cbiAgcHJpdmF0ZSBfZGlyQ2hhbmdlU3Vic2NyaXB0aW9uID0gU3Vic2NyaXB0aW9uLkVNUFRZO1xuXG4gIC8qKiBUaGUgdmFsdWUgb2YgdGhlIHNsaWRlciB3aGVuIHRoZSBzbGlkZSBzdGFydCBldmVudCBmaXJlcy4gKi9cbiAgcHJpdmF0ZSBfdmFsdWVPblNsaWRlU3RhcnQhOiBudW1iZXIgfCBudW1iZXJbXSB8IG51bGw7XG5cbiAgLyoqIFBvc2l0aW9uIG9mIHRoZSBwb2ludGVyIHdoZW4gdGhlIGRyYWdnaW5nIHN0YXJ0ZWQuICovXG4gIHByaXZhdGUgX3BvaW50ZXJQb3NpdGlvbk9uU3RhcnQhOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0gfCBudWxsO1xuXG4gIC8qKiBSZWZlcmVuY2UgdG8gdGhlIGlubmVyIHNsaWRlciB3cmFwcGVyIGVsZW1lbnQuICovXG4gIEBWaWV3Q2hpbGQoJ3NsaWRlcldyYXBwZXInKSBwcml2YXRlIF9zbGlkZXJXcmFwcGVyITogRWxlbWVudFJlZjtcblxuICAvKiogVGhlIHNsaWRlciB0aHVtYiB3aGljaCBpcyBjdXJyZW50bHkgdXNlZCAobGVmdCBvciByaWdodCkgKi9cbiAgcHJpdmF0ZSBfY3VycmVudFNsaWRlckRpciA9ICdsJztcblxuICAvKipcbiAgICogV2hldGhlciBtb3VzZSBldmVudHMgc2hvdWxkIGJlIGNvbnZlcnRlZCB0byBhIHNsaWRlciBwb3NpdGlvbiBieSBjYWxjdWxhdGluZyB0aGVpciBkaXN0YW5jZVxuICAgKiBmcm9tIHRoZSByaWdodCBvciBib3R0b20gZWRnZSBvZiB0aGUgc2xpZGVyIGFzIG9wcG9zZWQgdG8gdGhlIHRvcCBvciBsZWZ0LlxuICAgKi9cbiAgcHJpdmF0ZSBfc2hvdWxkSW52ZXJ0TW91c2VDb29yZHMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2dldERpcmVjdGlvbigpID09PSAncnRsJyAmJiAhdGhpcy52ZXJ0aWNhbCA/ICF0aGlzLl9pbnZlcnRBeGlzIDogdGhpcy5faW52ZXJ0QXhpcztcbiAgfVxuXG4gIC8qKiBUaGUgbGFuZ3VhZ2UgZGlyZWN0aW9uIGZvciB0aGlzIHNsaWRlciBlbGVtZW50LiAqL1xuICBwcml2YXRlIF9nZXREaXJlY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuX2RpciAmJiB0aGlzLl9kaXIudmFsdWUgPT09ICdydGwnID8gJ3J0bCcgOiAnbHRyJztcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgcHJpdmF0ZSBfZm9jdXNNb25pdG9yOiBGb2N1c01vbml0b3IsXG4gICAgcHJpdmF0ZSBfY2hhbmdlRGV0ZWN0b3JSZWY6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgX2RpcjogRGlyZWN0aW9uYWxpdHksXG4gICAgQEF0dHJpYnV0ZSgndGFiaW5kZXgnKSB0YWJJbmRleDogc3RyaW5nLFxuICAgIC8vIEBicmVha2luZy1jaGFuZ2UgNy4wLjAgYF9hbmltYXRpb25Nb2RlYCBwYXJhbWV0ZXIgdG8gYmUgbWFkZSByZXF1aXJlZC5cbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KEFOSU1BVElPTl9NT0RVTEVfVFlQRSkgcHVibGljIF9hbmltYXRpb25Nb2RlPzogc3RyaW5nLFxuICAgIHByaXZhdGUgX25nWm9uZT86IE5nWm9uZVxuICApIHtcbiAgICBzdXBlcihlbGVtZW50UmVmKTtcblxuICAgIHRoaXMudGFiSW5kZXggPSBwYXJzZUludCh0YWJJbmRleCwgMTApIHx8IDA7XG5cbiAgICB0aGlzLl9ydW5PdXRzaXplWm9uZSgoKSA9PiB7XG4gICAgICBjb25zdCBlbGVtZW50ID0gZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xuICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCB0aGlzLl9wb2ludGVyRG93biwgYWN0aXZlRXZlbnRPcHRpb25zKTtcbiAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIHRoaXMuX3BvaW50ZXJEb3duLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgIH0pO1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5fZm9jdXNNb25pdG9yLm1vbml0b3IodGhpcy5fZWxlbWVudFJlZiwgdHJ1ZSkuc3Vic2NyaWJlKChvcmlnaW46IEZvY3VzT3JpZ2luKSA9PiB7XG4gICAgICB0aGlzLl9pc0FjdGl2ZSA9ICEhb3JpZ2luICYmIG9yaWdpbiAhPT0gJ2tleWJvYXJkJztcbiAgICAgIHRoaXMuX2NoYW5nZURldGVjdG9yUmVmLmRldGVjdENoYW5nZXMoKTtcbiAgICB9KTtcbiAgICBpZiAodGhpcy5fZGlyKSB7XG4gICAgICB0aGlzLl9kaXJDaGFuZ2VTdWJzY3JpcHRpb24gPSB0aGlzLl9kaXIuY2hhbmdlLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuX2NoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgY29uc3QgZWxlbWVudCA9IHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcbiAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIHRoaXMuX3BvaW50ZXJEb3duLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIHRoaXMuX3BvaW50ZXJEb3duLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgIHRoaXMuX3JlbW92ZUdsb2JhbEV2ZW50cygpO1xuICAgIHRoaXMuX2ZvY3VzTW9uaXRvci5zdG9wTW9uaXRvcmluZyh0aGlzLl9lbGVtZW50UmVmKTtcbiAgICB0aGlzLl9kaXJDaGFuZ2VTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIF9vbk1vdXNlZW50ZXIoKSB7XG4gICAgaWYgKHRoaXMuZGlzYWJsZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBXZSBzYXZlIHRoZSBkaW1lbnNpb25zIG9mIHRoZSBzbGlkZXIgaGVyZSBzbyB3ZSBjYW4gdXNlIHRoZW0gdG8gdXBkYXRlIHRoZSBzcGFjaW5nIG9mIHRoZVxuICAgIC8vIHRpY2tzIGFuZCBkZXRlcm1pbmUgd2hlcmUgb24gdGhlIHNsaWRlciBjbGljayBhbmQgc2xpZGUgZXZlbnRzIGhhcHBlbi5cbiAgICB0aGlzLl9zbGlkZXJEaW1lbnNpb25zID0gdGhpcy5fZ2V0U2xpZGVyRGltZW5zaW9ucygpO1xuICAgIHRoaXMuX3VwZGF0ZVRpY2tJbnRlcnZhbFBlcmNlbnQoKTtcbiAgfVxuXG4gIF9vbkNsaWNrKGV2ZW50OiBNb3VzZUV2ZW50KSB7XG4gICAgaWYgKHRoaXMuZGlzYWJsZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgb2xkVmFsdWU7XG4gICAgaWYgKHRoaXMudmFsdWUgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgb2xkVmFsdWUgPSBbdGhpcy52YWx1ZVswXSwgdGhpcy52YWx1ZVsxXV07XG4gICAgfSBlbHNlIHtcbiAgICAgIG9sZFZhbHVlID0gdGhpcy52YWx1ZTtcbiAgICB9XG5cbiAgICB0aGlzLl9pc1NsaWRpbmcgPSBmYWxzZTtcbiAgICB0aGlzLl9mb2N1c0hvc3RFbGVtZW50KCk7XG5cbiAgICBpZiAoIXRoaXMuX3NsaWRlckRpbWVuc2lvbnMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy52ZXJ0aWNhbCA/IHRoaXMuX3NsaWRlckRpbWVuc2lvbnMudG9wIDogdGhpcy5fc2xpZGVyRGltZW5zaW9ucy5sZWZ0O1xuICAgIGNvbnN0IHNpemUgPSB0aGlzLnZlcnRpY2FsID8gdGhpcy5fc2xpZGVyRGltZW5zaW9ucy5oZWlnaHQgOiB0aGlzLl9zbGlkZXJEaW1lbnNpb25zLndpZHRoO1xuICAgIGNvbnN0IHBvc0NvbXBvbmVudCA9IHRoaXMudmVydGljYWwgPyBldmVudC5jbGllbnRZIDogZXZlbnQuY2xpZW50WDtcblxuICAgIC8vIFRoZSBleGFjdCB2YWx1ZSBpcyBjYWxjdWxhdGVkIGZyb20gdGhlIGV2ZW50IGFuZCB1c2VkIHRvIGZpbmQgdGhlIGNsb3Nlc3Qgc25hcCB2YWx1ZS5cbiAgICBsZXQgcGVyY2VudCA9IE51bWJlcih0aGlzLl9jbGFtcCgocG9zQ29tcG9uZW50IC0gb2Zmc2V0KSAvIHNpemUpKTtcblxuICAgIGlmICh0aGlzLl9zaG91bGRJbnZlcnRNb3VzZUNvb3JkcygpKSB7XG4gICAgICBwZXJjZW50ID0gMSAtIHBlcmNlbnQ7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgcGVyY2VudCA8PVxuICAgICAgKHRoaXMucGVyY2VudCBhcyBudW1iZXJbXSlbMF0gK1xuICAgICAgICAoKHRoaXMucGVyY2VudCBhcyBudW1iZXJbXSlbMV0gLSAodGhpcy5wZXJjZW50IGFzIG51bWJlcltdKVswXSkgLyAyXG4gICAgKSB7XG4gICAgICB0aGlzLl9jdXJyZW50U2xpZGVyRGlyID0gJ2wnO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9jdXJyZW50U2xpZGVyRGlyID0gJ3InO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9jdXJyZW50U2xpZGVyRGlyID09PSAnbCcpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZVZhbHVlRnJvbVBvc2l0aW9uTGVmdCh7IHg6IGV2ZW50LmNsaWVudFgsIHk6IGV2ZW50LmNsaWVudFkgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3VwZGF0ZVZhbHVlRnJvbVBvc2l0aW9uUmlnaHQoeyB4OiBldmVudC5jbGllbnRYLCB5OiBldmVudC5jbGllbnRZIH0pO1xuICAgIH1cblxuICAgIC8vIEVtaXQgYSBjaGFuZ2UgYW5kIGlucHV0IGV2ZW50IGlmIHRoZSB2YWx1ZSBjaGFuZ2VkLlxuICAgIGlmICh0aGlzLnZhbHVlIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgIGlmIChcbiAgICAgICAgKG9sZFZhbHVlIGFzIG51bWJlcltdKVswXSAhPT0gdGhpcy52YWx1ZVswXSB8fFxuICAgICAgICAob2xkVmFsdWUgYXMgbnVtYmVyW10pWzFdICE9PSB0aGlzLnZhbHVlWzFdXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5fZW1pdElucHV0RXZlbnQoKTtcbiAgICAgICAgdGhpcy5fZW1pdENoYW5nZUV2ZW50KCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChvbGRWYWx1ZSAhPT0gdGhpcy52YWx1ZSkge1xuICAgICAgICB0aGlzLl9lbWl0SW5wdXRFdmVudCgpO1xuICAgICAgICB0aGlzLl9lbWl0Q2hhbmdlRXZlbnQoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBfb25Gb2N1cygpIHtcbiAgICAvLyBXZSBzYXZlIHRoZSBkaW1lbnNpb25zIG9mIHRoZSBzbGlkZXIgaGVyZSBzbyB3ZSBjYW4gdXNlIHRoZW0gdG8gdXBkYXRlIHRoZSBzcGFjaW5nIG9mIHRoZVxuICAgIC8vIHRpY2tzIGFuZCBkZXRlcm1pbmUgd2hlcmUgb24gdGhlIHNsaWRlciBjbGljayBhbmQgc2xpZGUgZXZlbnRzIGhhcHBlbi5cbiAgICB0aGlzLl9zbGlkZXJEaW1lbnNpb25zID0gdGhpcy5fZ2V0U2xpZGVyRGltZW5zaW9ucygpO1xuICAgIHRoaXMuX3VwZGF0ZVRpY2tJbnRlcnZhbFBlcmNlbnQoKTtcbiAgfVxuXG4gIF9vbkJsdXIoKSB7XG4gICAgdGhpcy5vblRvdWNoZWQoKTtcbiAgfVxuXG4gIF9vbktleWRvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcbiAgICBpZiAodGhpcy5kaXNhYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBvbGRWYWx1ZTtcbiAgICBpZiAodGhpcy52YWx1ZSBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICBvbGRWYWx1ZSA9IFt0aGlzLnZhbHVlWzBdLCB0aGlzLnZhbHVlWzFdXTtcbiAgICB9IGVsc2Uge1xuICAgICAgb2xkVmFsdWUgPSB0aGlzLnZhbHVlO1xuICAgIH1cblxuICAgIHN3aXRjaCAoZXZlbnQua2V5Q29kZSkge1xuICAgICAgY2FzZSBQQUdFX1VQOlxuICAgICAgICB0aGlzLl9pbmNyZW1lbnQoMTApO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgUEFHRV9ET1dOOlxuICAgICAgICB0aGlzLl9pbmNyZW1lbnQoLTEwKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEVORDpcbiAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMubWF4O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgSE9NRTpcbiAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMubWluO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgTEVGVF9BUlJPVzpcbiAgICAgICAgLy8gTk9URTogRm9yIGEgc2lnaHRlZCB1c2VyIGl0IHdvdWxkIG1ha2UgbW9yZSBzZW5zZSB0aGF0IHdoZW4gdGhleSBwcmVzcyBhbiBhcnJvd1xuICAgICAgICAvLyBrZXkgb24gYW4gaW52ZXJ0ZWQgc2xpZGVyIHRoZSB0aHVtYiBtb3ZlcyBpbiB0aGF0IGRpcmVjdGlvbi4gSG93ZXZlciBmb3IgYSBibGluZFxuICAgICAgICAvLyB1c2VyLCBub3RoaW5nIGFib3V0IHRoZSBzbGlkZXIgaW5kaWNhdGVzIHRoYXQgaXQgaXMgaW52ZXJ0ZWQuIFRoZXkgd2lsbCBleHBlY3RcbiAgICAgICAgLy8gbGVmdCB0byBiZSBkZWNyZW1lbnQsIHJlZ2FyZGxlc3Mgb2YgaG93IGl0IGFwcGVhcnMgb24gdGhlIHNjcmVlbi4gRm9yIHNwZWFrZXJzXG4gICAgICAgIC8vIG9mUlRMIGxhbmd1YWdlcywgdGhleSBwcm9iYWJseSBleHBlY3QgbGVmdCB0byBtZWFuIGluY3JlbWVudC4gVGhlcmVmb3JlIHdlIGZsaXBcbiAgICAgICAgLy8gdGhlIG1lYW5pbmcgb2YgdGhlIHNpZGUgYXJyb3cga2V5cyBmb3IgUlRMLiBGb3IgaW52ZXJ0ZWQgc2xpZGVycyB3ZSBwcmVmZXIgYVxuICAgICAgICAvLyBnb29kIGExMXkgZXhwZXJpZW5jZSB0byBoYXZpbmcgaXQgXCJsb29rIHJpZ2h0XCIgZm9yIHNpZ2h0ZWQgdXNlcnMsIHRoZXJlZm9yZSB3ZSBkb1xuICAgICAgICAvLyBub3Qgc3dhcCB0aGUgbWVhbmluZy5cbiAgICAgICAgdGhpcy5faW5jcmVtZW50KHRoaXMuX2dldERpcmVjdGlvbigpID09PSAncnRsJyA/IDEgOiAtMSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBVUF9BUlJPVzpcbiAgICAgICAgdGhpcy5faW5jcmVtZW50KDEpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgUklHSFRfQVJST1c6XG4gICAgICAgIC8vIFNlZSBjb21tZW50IG9uIExFRlRfQVJST1cgYWJvdXQgdGhlIGNvbmRpdGlvbnMgdW5kZXIgd2hpY2ggd2UgZmxpcCB0aGUgbWVhbmluZy5cbiAgICAgICAgdGhpcy5faW5jcmVtZW50KHRoaXMuX2dldERpcmVjdGlvbigpID09PSAncnRsJyA/IC0xIDogMSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBET1dOX0FSUk9XOlxuICAgICAgICB0aGlzLl9pbmNyZW1lbnQoLTEpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIC8vIFJldHVybiBpZiB0aGUga2V5IGlzIG5vdCBvbmUgdGhhdCB3ZSBleHBsaWNpdGx5IGhhbmRsZSB0byBhdm9pZCBjYWxsaW5nXG4gICAgICAgIC8vIHByZXZlbnREZWZhdWx0IG9uIGl0LlxuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudmFsdWUgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgaWYgKFxuICAgICAgICAob2xkVmFsdWUgYXMgbnVtYmVyW10pWzBdICE9PSB0aGlzLnZhbHVlWzBdIHx8XG4gICAgICAgIChvbGRWYWx1ZSBhcyBudW1iZXJbXSlbMV0gIT09IHRoaXMudmFsdWVbMV1cbiAgICAgICkge1xuICAgICAgICB0aGlzLl9lbWl0SW5wdXRFdmVudCgpO1xuICAgICAgICB0aGlzLl9lbWl0Q2hhbmdlRXZlbnQoKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKG9sZFZhbHVlICE9PSB0aGlzLnZhbHVlKSB7XG4gICAgICAgIHRoaXMuX2VtaXRJbnB1dEV2ZW50KCk7XG4gICAgICAgIHRoaXMuX2VtaXRDaGFuZ2VFdmVudCgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuX2lzU2xpZGluZyA9IHRydWU7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgfVxuXG4gIF9vbktleXVwKCkge1xuICAgIHRoaXMuX2lzU2xpZGluZyA9IGZhbHNlO1xuICB9XG5cbiAgLyoqIENhbGxlZCB3aGVuIHRoZSB1c2VyIGhhcyBwdXQgdGhlaXIgcG9pbnRlciBkb3duIG9uIHRoZSBzbGlkZXIuICovXG4gIHByaXZhdGUgX3BvaW50ZXJEb3duID0gKGV2ZW50OiBUb3VjaEV2ZW50IHwgTW91c2VFdmVudCkgPT4ge1xuICAgIC8vIERvbid0IGRvIGFueXRoaW5nIGlmIHRoZSBzbGlkZXIgaXMgZGlzYWJsZWQgb3IgdGhlXG4gICAgLy8gdXNlciBpcyB1c2luZyBhbnl0aGluZyBvdGhlciB0aGFuIHRoZSBtYWluIG1vdXNlIGJ1dHRvbi5cbiAgICBpZiAodGhpcy5kaXNhYmxlZCB8fCB0aGlzLl9pc1NsaWRpbmcgfHwgKCFpc1RvdWNoRXZlbnQoZXZlbnQpICYmIGV2ZW50LmJ1dHRvbiAhPT0gMCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmNhbGN1bGF0ZUluaXRpYWxTbGlkZURpcmVjdGlvbihldmVudCk7XG5cbiAgICB0aGlzLl9ydW5JbnNpZGVab25lKCgpID0+IHtcbiAgICAgIGNvbnN0IG9sZFZhbHVlID0gdGhpcy52YWx1ZTtcbiAgICAgIGNvbnN0IHBvaW50ZXJQb3NpdGlvbiA9IGdldFBvaW50ZXJQb3NpdGlvbk9uUGFnZShldmVudCk7XG4gICAgICB0aGlzLl9pc1NsaWRpbmcgPSB0cnVlO1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHRoaXMuX2ZvY3VzSG9zdEVsZW1lbnQoKTtcbiAgICAgIHRoaXMuX29uTW91c2VlbnRlcigpOyAvLyBTaW11bGF0ZSBtb3VzZWVudGVyIGluIGNhc2UgdGhpcyBpcyBhIG1vYmlsZSBkZXZpY2UuXG4gICAgICB0aGlzLl9iaW5kR2xvYmFsRXZlbnRzKGV2ZW50KTtcbiAgICAgIHRoaXMuX2ZvY3VzSG9zdEVsZW1lbnQoKTtcblxuICAgICAgLy8gVE9ETzpcbiAgICAgIC8vIHRoaXMuX3VwZGF0ZVZhbHVlRnJvbVBvc2l0aW9uKHBvaW50ZXJQb3NpdGlvbik7XG4gICAgICBpZiAodGhpcy52YWx1ZSBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgIGlmICh0aGlzLl9jdXJyZW50U2xpZGVyRGlyID09PSAnbCcpIHtcbiAgICAgICAgICB0aGlzLl91cGRhdGVWYWx1ZUZyb21Qb3NpdGlvbkxlZnQocG9pbnRlclBvc2l0aW9uKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLl9jdXJyZW50U2xpZGVyRGlyID09PSAncicpIHtcbiAgICAgICAgICB0aGlzLl91cGRhdGVWYWx1ZUZyb21Qb3NpdGlvblJpZ2h0KHBvaW50ZXJQb3NpdGlvbik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX3VwZGF0ZVZhbHVlRnJvbVBvc2l0aW9uTGVmdChwb2ludGVyUG9zaXRpb24pO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl92YWx1ZU9uU2xpZGVTdGFydCA9IHRoaXMudmFsdWU7XG4gICAgICB0aGlzLl9wb2ludGVyUG9zaXRpb25PblN0YXJ0ID0gcG9pbnRlclBvc2l0aW9uO1xuXG4gICAgICAvLyBFbWl0IGEgY2hhbmdlIGFuZCBpbnB1dCBldmVudCBpZiB0aGUgdmFsdWUgY2hhbmdlZC5cbiAgICAgIGlmIChvbGRWYWx1ZSAhPT0gdGhpcy52YWx1ZSkge1xuICAgICAgICB0aGlzLl9lbWl0SW5wdXRFdmVudCgpO1xuICAgICAgICB0aGlzLl9lbWl0Q2hhbmdlRXZlbnQoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcblxuICAvKipcbiAgICogQ2FsbGVkIHdoZW4gdGhlIHVzZXIgaGFzIG1vdmVkIHRoZWlyIHBvaW50ZXIgYWZ0ZXJcbiAgICogc3RhcnRpbmcgdG8gZHJhZy4gQm91bmQgb24gdGhlIGRvY3VtZW50IGxldmVsLlxuICAgKi9cbiAgcHJpdmF0ZSBfcG9pbnRlck1vdmUgPSAoZXZlbnQ6IFRvdWNoRXZlbnQgfCBNb3VzZUV2ZW50KSA9PiB7XG4gICAgaWYgKHRoaXMuX2lzU2xpZGluZykge1xuICAgICAgdGhpcy5jYWxjdWxhdGVJbml0aWFsU2xpZGVEaXJlY3Rpb24oZXZlbnQpO1xuXG4gICAgICAvLyBQcmV2ZW50IHRoZSBzbGlkZSBmcm9tIHNlbGVjdGluZyBhbnl0aGluZyBlbHNlLlxuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGNvbnN0IG9sZFZhbHVlID0gdGhpcy52YWx1ZTtcblxuICAgICAgLy8gVE9ETzpcbiAgICAgIC8vIHRoaXMuX3VwZGF0ZVZhbHVlRnJvbVBvc2l0aW9uKGdldFBvaW50ZXJQb3NpdGlvbk9uUGFnZShldmVudCkpO1xuICAgICAgY29uc3QgcG9pbnRlclBvc2l0aW9uID0gZ2V0UG9pbnRlclBvc2l0aW9uT25QYWdlKGV2ZW50KTtcbiAgICAgIGlmICh0aGlzLl9jdXJyZW50U2xpZGVyRGlyID09PSAnbCcpIHtcbiAgICAgICAgdGhpcy5fdXBkYXRlVmFsdWVGcm9tUG9zaXRpb25MZWZ0KHBvaW50ZXJQb3NpdGlvbik7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuX2N1cnJlbnRTbGlkZXJEaXIgPT09ICdyJykge1xuICAgICAgICB0aGlzLl91cGRhdGVWYWx1ZUZyb21Qb3NpdGlvblJpZ2h0KHBvaW50ZXJQb3NpdGlvbik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoIXRoaXMuaXNSYW5nZVNsaWRlcigpKSB7XG4gICAgICAgICAgdGhpcy5fdXBkYXRlVmFsdWVGcm9tUG9zaXRpb25MZWZ0KHBvaW50ZXJQb3NpdGlvbik7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gTmF0aXZlIHJhbmdlIGVsZW1lbnRzIGFsd2F5cyBlbWl0IGBpbnB1dGAgZXZlbnRzIHdoZW4gdGhlIHZhbHVlIGNoYW5nZWQgd2hpbGUgc2xpZGluZy5cbiAgICAgIGlmIChvbGRWYWx1ZSAhPT0gdGhpcy52YWx1ZSkge1xuICAgICAgICB0aGlzLl9lbWl0SW5wdXRFdmVudCgpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICAvKiogQ2FsbGVkIHdoZW4gdGhlIHVzZXIgaGFzIGxpZnRlZCB0aGVpciBwb2ludGVyLiBCb3VuZCBvbiB0aGUgZG9jdW1lbnQgbGV2ZWwuICovXG4gIHByaXZhdGUgX3BvaW50ZXJVcCA9IChldmVudDogVG91Y2hFdmVudCB8IE1vdXNlRXZlbnQpID0+IHtcbiAgICBpZiAodGhpcy5faXNTbGlkaW5nKSB7XG4gICAgICBjb25zdCBwb2ludGVyUG9zaXRpb25PblN0YXJ0ID0gdGhpcy5fcG9pbnRlclBvc2l0aW9uT25TdGFydDtcbiAgICAgIGNvbnN0IGN1cnJlbnRQb2ludGVyUG9zaXRpb24gPSBnZXRQb2ludGVyUG9zaXRpb25PblBhZ2UoZXZlbnQpO1xuXG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgdGhpcy5fcmVtb3ZlR2xvYmFsRXZlbnRzKCk7XG4gICAgICB0aGlzLl92YWx1ZU9uU2xpZGVTdGFydCA9IHRoaXMuX3BvaW50ZXJQb3NpdGlvbk9uU3RhcnQgPSBudWxsO1xuICAgICAgdGhpcy5faXNTbGlkaW5nID0gZmFsc2U7XG5cbiAgICAgIGlmIChcbiAgICAgICAgdGhpcy5fdmFsdWVPblNsaWRlU3RhcnQgIT09IHRoaXMudmFsdWUgJiZcbiAgICAgICAgIXRoaXMuZGlzYWJsZWQgJiZcbiAgICAgICAgcG9pbnRlclBvc2l0aW9uT25TdGFydCAmJlxuICAgICAgICAocG9pbnRlclBvc2l0aW9uT25TdGFydC54ICE9PSBjdXJyZW50UG9pbnRlclBvc2l0aW9uLnggfHxcbiAgICAgICAgICBwb2ludGVyUG9zaXRpb25PblN0YXJ0LnkgIT09IGN1cnJlbnRQb2ludGVyUG9zaXRpb24ueSlcbiAgICAgICkge1xuICAgICAgICB0aGlzLl9lbWl0Q2hhbmdlRXZlbnQoKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIEJpbmRzIG91ciBnbG9iYWwgbW92ZSBhbmQgZW5kIGV2ZW50cy4gVGhleSdyZSBib3VuZCBhdCB0aGUgZG9jdW1lbnQgbGV2ZWwgYW5kIG9ubHkgd2hpbGVcbiAgICogZHJhZ2dpbmcgc28gdGhhdCB0aGUgdXNlciBkb2Vzbid0IGhhdmUgdG8ga2VlcCB0aGVpciBwb2ludGVyIGV4YWN0bHkgb3ZlciB0aGUgc2xpZGVyXG4gICAqIGFzIHRoZXkncmUgc3dpcGluZyBhY3Jvc3MgdGhlIHNjcmVlbi5cbiAgICovXG4gIHByaXZhdGUgX2JpbmRHbG9iYWxFdmVudHModHJpZ2dlckV2ZW50OiBUb3VjaEV2ZW50IHwgTW91c2VFdmVudCkge1xuICAgIGlmICh0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnICYmIGRvY3VtZW50KSB7XG4gICAgICBjb25zdCBpc1RvdWNoID0gaXNUb3VjaEV2ZW50KHRyaWdnZXJFdmVudCk7XG4gICAgICBjb25zdCBtb3ZlRXZlbnROYW1lID0gaXNUb3VjaCA/ICd0b3VjaG1vdmUnIDogJ21vdXNlbW92ZSc7XG4gICAgICBjb25zdCBlbmRFdmVudE5hbWUgPSBpc1RvdWNoID8gJ3RvdWNoZW5kJyA6ICdtb3VzZXVwJztcbiAgICAgIGRvY3VtZW50LmJvZHkuYWRkRXZlbnRMaXN0ZW5lcihtb3ZlRXZlbnROYW1lLCB0aGlzLl9wb2ludGVyTW92ZSwgYWN0aXZlRXZlbnRPcHRpb25zKTtcbiAgICAgIGRvY3VtZW50LmJvZHkuYWRkRXZlbnRMaXN0ZW5lcihlbmRFdmVudE5hbWUsIHRoaXMuX3BvaW50ZXJVcCwgYWN0aXZlRXZlbnRPcHRpb25zKTtcbiAgICB9XG4gIH1cblxuICAvKiogUmVtb3ZlcyBhbnkgZ2xvYmFsIGV2ZW50IGxpc3RlbmVycyB0aGF0IHdlIG1heSBoYXZlIGFkZGVkLiAqL1xuICBwcml2YXRlIF9yZW1vdmVHbG9iYWxFdmVudHMoKSB7XG4gICAgaWYgKHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcgJiYgZG9jdW1lbnQpIHtcbiAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5fcG9pbnRlck1vdmUsIGFjdGl2ZUV2ZW50T3B0aW9ucyk7XG4gICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLl9wb2ludGVyVXAsIGFjdGl2ZUV2ZW50T3B0aW9ucyk7XG4gICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIHRoaXMuX3BvaW50ZXJNb3ZlLCBhY3RpdmVFdmVudE9wdGlvbnMpO1xuICAgICAgZG9jdW1lbnQuYm9keS5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaGVuZCcsIHRoaXMuX3BvaW50ZXJVcCwgYWN0aXZlRXZlbnRPcHRpb25zKTtcbiAgICB9XG4gIH1cblxuICAvKiogSW5jcmVtZW50cyB0aGUgc2xpZGVyIGJ5IHRoZSBnaXZlbiBudW1iZXIgb2Ygc3RlcHMgKG5lZ2F0aXZlIG51bWJlciBkZWNyZW1lbnRzKS4gKi9cbiAgcHJpdmF0ZSBfaW5jcmVtZW50KG51bVN0ZXBzOiBudW1iZXIpIHtcbiAgICBpZiAodGhpcy52YWx1ZSBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICB0aGlzLnZhbHVlID0gdGhpcy5fY2xhbXAoXG4gICAgICAgIFsodGhpcy52YWx1ZVswXSB8fCAwKSArIHRoaXMuc3RlcCAqIG51bVN0ZXBzLCAodGhpcy52YWx1ZVsxXSB8fCAwKSArIHRoaXMuc3RlcCAqIG51bVN0ZXBzXSxcbiAgICAgICAgdGhpcy5taW4sXG4gICAgICAgIHRoaXMubWF4XG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnZhbHVlID0gdGhpcy5fY2xhbXAoKHRoaXMudmFsdWUgfHwgMCkgKyB0aGlzLnN0ZXAgKiBudW1TdGVwcywgdGhpcy5taW4sIHRoaXMubWF4KTtcbiAgICB9XG4gIH1cblxuICAvKiogQ2FsY3VsYXRlIHRoZSBuZXcgdmFsdWUgZnJvbSB0aGUgbmV3IHBoeXNpY2FsIGxvY2F0aW9uLiBUaGUgdmFsdWUgd2lsbCBhbHdheXMgYmUgc25hcHBlZC4gKi9cbiAgcHJpdmF0ZSBfdXBkYXRlVmFsdWVGcm9tUG9zaXRpb24ocG9zOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0pIHtcbiAgICBpZiAoIXRoaXMuX3NsaWRlckRpbWVuc2lvbnMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLnZlcnRpY2FsID8gdGhpcy5fc2xpZGVyRGltZW5zaW9ucy50b3AgOiB0aGlzLl9zbGlkZXJEaW1lbnNpb25zLmxlZnQ7XG4gICAgY29uc3Qgc2l6ZSA9IHRoaXMudmVydGljYWwgPyB0aGlzLl9zbGlkZXJEaW1lbnNpb25zLmhlaWdodCA6IHRoaXMuX3NsaWRlckRpbWVuc2lvbnMud2lkdGg7XG4gICAgY29uc3QgcG9zQ29tcG9uZW50ID0gdGhpcy52ZXJ0aWNhbCA/IHBvcy55IDogcG9zLng7XG5cbiAgICAvLyBUaGUgZXhhY3QgdmFsdWUgaXMgY2FsY3VsYXRlZCBmcm9tIHRoZSBldmVudCBhbmQgdXNlZCB0byBmaW5kIHRoZSBjbG9zZXN0IHNuYXAgdmFsdWUuXG4gICAgbGV0IHBlcmNlbnQgPSB0aGlzLl9jbGFtcCgocG9zQ29tcG9uZW50IC0gb2Zmc2V0KSAvIHNpemUpO1xuXG4gICAgaWYgKHRoaXMuX3Nob3VsZEludmVydE1vdXNlQ29vcmRzKCkpIHtcbiAgICAgIHBlcmNlbnQgPSAxIC0gKHBlcmNlbnQgYXMgYW55KTtcbiAgICB9XG5cbiAgICAvLyBTaW5jZSB0aGUgc3RlcHMgbWF5IG5vdCBkaXZpZGUgY2xlYW5seSBpbnRvIHRoZSBtYXggdmFsdWUsIGlmIHRoZSB1c2VyXG4gICAgLy8gc2xpZCB0byAwIG9yIDEwMCBwZXJjZW50LCB3ZSBqdW1wIHRvIHRoZSBtaW4vbWF4IHZhbHVlLiBUaGlzIGFwcHJvYWNoXG4gICAgLy8gaXMgc2xpZ2h0bHkgbW9yZSBpbnR1aXRpdmUgdGhhbiB1c2luZyBgTWF0aC5jZWlsYCBiZWxvdywgYmVjYXVzZSBpdFxuICAgIC8vIGZvbGxvd3MgdGhlIHVzZXIncyBwb2ludGVyIGNsb3Nlci5cbiAgICBpZiAocGVyY2VudCA9PT0gMCkge1xuICAgICAgdGhpcy52YWx1ZSA9IHRoaXMubWluO1xuICAgIH0gZWxzZSBpZiAocGVyY2VudCA9PT0gMSkge1xuICAgICAgdGhpcy52YWx1ZSA9IHRoaXMubWF4O1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBleGFjdFZhbHVlID0gdGhpcy5fY2FsY3VsYXRlVmFsdWUocGVyY2VudCk7XG5cbiAgICAgIC8vIFRoaXMgY2FsY3VsYXRpb24gZmluZHMgdGhlIGNsb3Nlc3Qgc3RlcCBieSBmaW5kaW5nIHRoZSBjbG9zZXN0XG4gICAgICAvLyB3aG9sZSBudW1iZXIgZGl2aXNpYmxlIGJ5IHRoZSBzdGVwIHJlbGF0aXZlIHRvIHRoZSBtaW4uXG4gICAgICBjb25zdCBjbG9zZXN0VmFsdWUgPVxuICAgICAgICBNYXRoLnJvdW5kKCgoZXhhY3RWYWx1ZSBhcyBhbnkpIC0gdGhpcy5taW4pIC8gdGhpcy5zdGVwKSAqIHRoaXMuc3RlcCArIHRoaXMubWluO1xuXG4gICAgICAvLyBUaGUgdmFsdWUgbmVlZHMgdG8gc25hcCB0byB0aGUgbWluIGFuZCBtYXguXG4gICAgICB0aGlzLnZhbHVlID0gdGhpcy5fY2xhbXAoY2xvc2VzdFZhbHVlLCB0aGlzLm1pbiwgdGhpcy5tYXgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBDYWxjdWxhdGUgdGhlIG5ldyB2YWx1ZSBmcm9tIHRoZSBuZXcgcGh5c2ljYWwgbG9jYXRpb24uIFRoZSB2YWx1ZSB3aWxsIGFsd2F5cyBiZSBzbmFwcGVkLiAqL1xuICBwcml2YXRlIF91cGRhdGVWYWx1ZUZyb21Qb3NpdGlvbkxlZnQocG9zOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0pIHtcbiAgICBpZiAoIXRoaXMuX3NsaWRlckRpbWVuc2lvbnMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLnZlcnRpY2FsID8gdGhpcy5fc2xpZGVyRGltZW5zaW9ucy50b3AgOiB0aGlzLl9zbGlkZXJEaW1lbnNpb25zLmxlZnQ7XG4gICAgY29uc3Qgc2l6ZSA9IHRoaXMudmVydGljYWwgPyB0aGlzLl9zbGlkZXJEaW1lbnNpb25zLmhlaWdodCA6IHRoaXMuX3NsaWRlckRpbWVuc2lvbnMud2lkdGg7XG4gICAgY29uc3QgcG9zQ29tcG9uZW50ID0gdGhpcy52ZXJ0aWNhbCA/IHBvcy55IDogcG9zLng7XG5cbiAgICAvLyBUaGUgZXhhY3QgdmFsdWUgaXMgY2FsY3VsYXRlZCBmcm9tIHRoZSBldmVudCBhbmQgdXNlZCB0byBmaW5kIHRoZSBjbG9zZXN0IHNuYXAgdmFsdWUuXG4gICAgbGV0IHBlcmNlbnQgPSBOdW1iZXIodGhpcy5fY2xhbXAoKHBvc0NvbXBvbmVudCAtIG9mZnNldCkgLyBzaXplKSk7XG5cbiAgICBpZiAodGhpcy5fc2hvdWxkSW52ZXJ0TW91c2VDb29yZHMoKSkge1xuICAgICAgcGVyY2VudCA9IDEgLSBwZXJjZW50O1xuICAgIH1cblxuICAgIC8vIFNpbmNlIHRoZSBzdGVwcyBtYXkgbm90IGRpdmlkZSBjbGVhbmx5IGludG8gdGhlIG1heCB2YWx1ZSwgaWYgdGhlIHVzZXJcbiAgICAvLyBzbGlkIHRvIDAgb3IgMTAwIHBlcmNlbnQsIHdlIGp1bXAgdG8gdGhlIG1pbi9tYXggdmFsdWUuIFRoaXMgYXBwcm9hY2hcbiAgICAvLyBpcyBzbGlnaHRseSBtb3JlIGludHVpdGl2ZSB0aGFuIHVzaW5nIGBNYXRoLmNlaWxgIGJlbG93LCBiZWNhdXNlIGl0XG4gICAgLy8gZm9sbG93cyB0aGUgdXNlcidzIHBvaW50ZXIgY2xvc2VyLlxuICAgIGlmIChwZXJjZW50ID09PSAwKSB7XG4gICAgICBpZiAodGhpcy52YWx1ZSBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSBbdGhpcy5taW4sIHRoaXMudmFsdWVbMV1dO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMubWluO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocGVyY2VudCA9PT0gMSkge1xuICAgICAgaWYgKHRoaXMudmFsdWUgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICB0aGlzLnZhbHVlID0gW3RoaXMubWF4LCB0aGlzLnZhbHVlWzFdXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSB0aGlzLm1heDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgZXhhY3RWYWx1ZSA9IHRoaXMuX2NhbGN1bGF0ZVZhbHVlKHBlcmNlbnQpO1xuXG4gICAgICAvLyBUaGlzIGNhbGN1bGF0aW9uIGZpbmRzIHRoZSBjbG9zZXN0IHN0ZXAgYnkgZmluZGluZyB0aGUgY2xvc2VzdFxuICAgICAgLy8gd2hvbGUgbnVtYmVyIGRpdmlzaWJsZSBieSB0aGUgc3RlcCByZWxhdGl2ZSB0byB0aGUgbWluLlxuICAgICAgY29uc3QgY2xvc2VzdFZhbHVlID1cbiAgICAgICAgTWF0aC5yb3VuZCgoTnVtYmVyKGV4YWN0VmFsdWUpIC0gdGhpcy5taW4pIC8gdGhpcy5zdGVwKSAqIHRoaXMuc3RlcCArIHRoaXMubWluO1xuXG4gICAgICAvLyBUaGUgdmFsdWUgbmVlZHMgdG8gc25hcCB0byB0aGUgbWluIGFuZCBtYXguXG4gICAgICBpZiAodGhpcy52YWx1ZSBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSBbTnVtYmVyKHRoaXMuX2NsYW1wKGNsb3Nlc3RWYWx1ZSwgdGhpcy5taW4sIHRoaXMubWF4KSksIHRoaXMudmFsdWVbMV1dO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMuX2NsYW1wKGNsb3Nlc3RWYWx1ZSwgdGhpcy5taW4sIHRoaXMubWF4KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKiogQ2FsY3VsYXRlIHRoZSBuZXcgdmFsdWUgZnJvbSB0aGUgbmV3IHBoeXNpY2FsIGxvY2F0aW9uLiBUaGUgdmFsdWUgd2lsbCBhbHdheXMgYmUgc25hcHBlZC4gKi9cbiAgcHJpdmF0ZSBfdXBkYXRlVmFsdWVGcm9tUG9zaXRpb25SaWdodChwb3M6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSkge1xuICAgIGlmICghdGhpcy5fc2xpZGVyRGltZW5zaW9ucykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMudmVydGljYWwgPyB0aGlzLl9zbGlkZXJEaW1lbnNpb25zLnRvcCA6IHRoaXMuX3NsaWRlckRpbWVuc2lvbnMubGVmdDtcbiAgICBjb25zdCBzaXplID0gdGhpcy52ZXJ0aWNhbCA/IHRoaXMuX3NsaWRlckRpbWVuc2lvbnMuaGVpZ2h0IDogdGhpcy5fc2xpZGVyRGltZW5zaW9ucy53aWR0aDtcbiAgICBjb25zdCBwb3NDb21wb25lbnQgPSB0aGlzLnZlcnRpY2FsID8gcG9zLnkgOiBwb3MueDtcblxuICAgIC8vIFRoZSBleGFjdCB2YWx1ZSBpcyBjYWxjdWxhdGVkIGZyb20gdGhlIGV2ZW50IGFuZCB1c2VkIHRvIGZpbmQgdGhlIGNsb3Nlc3Qgc25hcCB2YWx1ZS5cbiAgICBsZXQgcGVyY2VudCA9IE51bWJlcih0aGlzLl9jbGFtcCgocG9zQ29tcG9uZW50IC0gb2Zmc2V0KSAvIHNpemUpKTtcblxuICAgIGlmICh0aGlzLl9zaG91bGRJbnZlcnRNb3VzZUNvb3JkcygpKSB7XG4gICAgICBwZXJjZW50ID0gMSAtIHBlcmNlbnQ7XG4gICAgfVxuXG4gICAgLy8gU2luY2UgdGhlIHN0ZXBzIG1heSBub3QgZGl2aWRlIGNsZWFubHkgaW50byB0aGUgbWF4IHZhbHVlLCBpZiB0aGUgdXNlclxuICAgIC8vIHNsaWQgdG8gMCBvciAxMDAgcGVyY2VudCwgd2UganVtcCB0byB0aGUgbWluL21heCB2YWx1ZS4gVGhpcyBhcHByb2FjaFxuICAgIC8vIGlzIHNsaWdodGx5IG1vcmUgaW50dWl0aXZlIHRoYW4gdXNpbmcgYE1hdGguY2VpbGAgYmVsb3csIGJlY2F1c2UgaXRcbiAgICAvLyBmb2xsb3dzIHRoZSB1c2VyJ3MgcG9pbnRlciBjbG9zZXIuXG4gICAgaWYgKHBlcmNlbnQgPT09IDApIHtcbiAgICAgIGlmICh0aGlzLnZhbHVlIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IFt0aGlzLnZhbHVlWzBdLCB0aGlzLm1pbl07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5taW47XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChwZXJjZW50ID09PSAxKSB7XG4gICAgICBpZiAodGhpcy52YWx1ZSBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSBbdGhpcy52YWx1ZVswXSwgdGhpcy5tYXhdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMubWF4O1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBleGFjdFZhbHVlID0gdGhpcy5fY2FsY3VsYXRlVmFsdWUocGVyY2VudCk7XG5cbiAgICAgIC8vIFRoaXMgY2FsY3VsYXRpb24gZmluZHMgdGhlIGNsb3Nlc3Qgc3RlcCBieSBmaW5kaW5nIHRoZSBjbG9zZXN0XG4gICAgICAvLyB3aG9sZSBudW1iZXIgZGl2aXNpYmxlIGJ5IHRoZSBzdGVwIHJlbGF0aXZlIHRvIHRoZSBtaW4uXG4gICAgICBjb25zdCBjbG9zZXN0VmFsdWUgPVxuICAgICAgICBNYXRoLnJvdW5kKChOdW1iZXIoZXhhY3RWYWx1ZSkgLSB0aGlzLm1pbikgLyB0aGlzLnN0ZXApICogdGhpcy5zdGVwICsgdGhpcy5taW47XG5cbiAgICAgIC8vIFRoZSB2YWx1ZSBuZWVkcyB0byBzbmFwIHRvIHRoZSBtaW4gYW5kIG1heC5cbiAgICAgIGlmICh0aGlzLnZhbHVlIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IFt0aGlzLnZhbHVlWzBdLCBOdW1iZXIodGhpcy5fY2xhbXAoY2xvc2VzdFZhbHVlLCB0aGlzLm1pbiwgdGhpcy5tYXgpKV07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5fY2xhbXAoY2xvc2VzdFZhbHVlLCB0aGlzLm1pbiwgdGhpcy5tYXgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKiBFbWl0cyBhIGNoYW5nZSBldmVudCBpZiB0aGUgY3VycmVudCB2YWx1ZSBpcyBkaWZmZXJlbnQgZnJvbSB0aGUgbGFzdCBlbWl0dGVkIHZhbHVlLiAqL1xuICBwcml2YXRlIF9lbWl0Q2hhbmdlRXZlbnQoKSB7XG4gICAgdGhpcy5fY29udHJvbFZhbHVlQWNjZXNzb3JDaGFuZ2VGbih0aGlzLnZhbHVlKTtcbiAgICB0aGlzLnZhbHVlQ2hhbmdlLmVtaXQodGhpcy52YWx1ZSk7XG4gICAgdGhpcy5jaGFuZ2UuZW1pdCh0aGlzLl9jcmVhdGVDaGFuZ2VFdmVudCgpKTtcbiAgfVxuXG4gIC8qKiBFbWl0cyBhbiBpbnB1dCBldmVudCB3aGVuIHRoZSBjdXJyZW50IHZhbHVlIGlzIGRpZmZlcmVudCBmcm9tIHRoZSBsYXN0IGVtaXR0ZWQgdmFsdWUuICovXG4gIHByaXZhdGUgX2VtaXRJbnB1dEV2ZW50KCkge1xuICAgIHRoaXMuaW5wdXQuZW1pdCh0aGlzLl9jcmVhdGVDaGFuZ2VFdmVudCgpKTtcbiAgfVxuXG4gIC8qKiBVcGRhdGVzIHRoZSBhbW91bnQgb2Ygc3BhY2UgYmV0d2VlbiB0aWNrcyBhcyBhIHBlcmNlbnRhZ2Ugb2YgdGhlIHdpZHRoIG9mIHRoZSBzbGlkZXIuICovXG4gIHByaXZhdGUgX3VwZGF0ZVRpY2tJbnRlcnZhbFBlcmNlbnQoKSB7XG4gICAgaWYgKCF0aGlzLnRpY2tJbnRlcnZhbCB8fCAhdGhpcy5fc2xpZGVyRGltZW5zaW9ucykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnRpY2tJbnRlcnZhbCA9PT0gJ2F1dG8nKSB7XG4gICAgICBjb25zdCB0cmFja1NpemUgPSB0aGlzLnZlcnRpY2FsXG4gICAgICAgID8gdGhpcy5fc2xpZGVyRGltZW5zaW9ucy5oZWlnaHRcbiAgICAgICAgOiB0aGlzLl9zbGlkZXJEaW1lbnNpb25zLndpZHRoO1xuICAgICAgY29uc3QgcGl4ZWxzUGVyU3RlcCA9ICh0cmFja1NpemUgKiB0aGlzLnN0ZXApIC8gKHRoaXMubWF4IC0gdGhpcy5taW4pO1xuICAgICAgY29uc3Qgc3RlcHNQZXJUaWNrID0gTWF0aC5jZWlsKE1JTl9BVVRPX1RJQ0tfU0VQQVJBVElPTiAvIHBpeGVsc1BlclN0ZXApO1xuICAgICAgY29uc3QgcGl4ZWxzUGVyVGljayA9IHN0ZXBzUGVyVGljayAqIHRoaXMuc3RlcDtcbiAgICAgIHRoaXMuX3RpY2tJbnRlcnZhbFBlcmNlbnQgPSBwaXhlbHNQZXJUaWNrIC8gdHJhY2tTaXplO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl90aWNrSW50ZXJ2YWxQZXJjZW50ID0gKHRoaXMudGlja0ludGVydmFsICogdGhpcy5zdGVwKSAvICh0aGlzLm1heCAtIHRoaXMubWluKTtcbiAgICB9XG4gIH1cblxuICAvKiogQ3JlYXRlcyBhIHNsaWRlciBjaGFuZ2Ugb2JqZWN0IGZyb20gdGhlIHNwZWNpZmllZCB2YWx1ZS4gKi9cbiAgcHJpdmF0ZSBfY3JlYXRlQ2hhbmdlRXZlbnQodmFsdWUgPSB0aGlzLnZhbHVlKTogTXR4U2xpZGVyQ2hhbmdlIHtcbiAgICBjb25zdCBldmVudCA9IG5ldyBNdHhTbGlkZXJDaGFuZ2UoKTtcblxuICAgIGV2ZW50LnNvdXJjZSA9IHRoaXM7XG4gICAgZXZlbnQudmFsdWUgPSB2YWx1ZTtcblxuICAgIHJldHVybiBldmVudDtcbiAgfVxuXG4gIC8qKiBDYWxjdWxhdGVzIHRoZSBwZXJjZW50YWdlIG9mIHRoZSBzbGlkZXIgdGhhdCBhIHZhbHVlIGlzLiAqL1xuICBwcml2YXRlIF9jYWxjdWxhdGVQZXJjZW50YWdlKHZhbHVlOiBudW1iZXIgfCBudW1iZXJbXSB8IG51bGwpIHtcbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgcmV0dXJuIFtcbiAgICAgICAgKCh2YWx1ZVswXSB8fCAwKSAtIHRoaXMubWluKSAvICh0aGlzLm1heCAtIHRoaXMubWluKSxcbiAgICAgICAgKCh2YWx1ZVsxXSB8fCAwKSAtIHRoaXMubWluKSAvICh0aGlzLm1heCAtIHRoaXMubWluKSxcbiAgICAgIF07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAoKHZhbHVlIHx8IDApIC0gdGhpcy5taW4pIC8gKHRoaXMubWF4IC0gdGhpcy5taW4pO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBDYWxjdWxhdGVzIHRoZSB2YWx1ZSBhIHBlcmNlbnRhZ2Ugb2YgdGhlIHNsaWRlciBjb3JyZXNwb25kcyB0by4gKi9cbiAgcHJpdmF0ZSBfY2FsY3VsYXRlVmFsdWUocGVyY2VudGFnZTogbnVtYmVyIHwgbnVtYmVyW10pIHtcbiAgICBpZiAocGVyY2VudGFnZSBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICByZXR1cm4gW1xuICAgICAgICB0aGlzLm1pbiArIHBlcmNlbnRhZ2VbMF0gKiAodGhpcy5tYXggLSB0aGlzLm1pbiksXG4gICAgICAgIHRoaXMubWluICsgcGVyY2VudGFnZVsxXSAqICh0aGlzLm1heCAtIHRoaXMubWluKSxcbiAgICAgIF07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLm1pbiArIHBlcmNlbnRhZ2UgKiAodGhpcy5tYXggLSB0aGlzLm1pbik7XG4gICAgfVxuICB9XG5cbiAgLyoqIFJldHVybiBhIG51bWJlciBiZXR3ZWVuIHR3byBudW1iZXJzLiAqL1xuICBwcml2YXRlIF9jbGFtcCh2YWx1ZTogbnVtYmVyIHwgbnVtYmVyW10sIG1pbiA9IDAsIG1heCA9IDEpIHtcbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgcmV0dXJuIFtNYXRoLm1heChtaW4sIE1hdGgubWluKHZhbHVlWzBdLCBtYXgpKSwgTWF0aC5tYXgobWluLCBNYXRoLm1pbih2YWx1ZVsxXSwgbWF4KSldO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gTWF0aC5tYXgobWluLCBNYXRoLm1pbih2YWx1ZSwgbWF4KSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgYm91bmRpbmcgY2xpZW50IHJlY3Qgb2YgdGhlIHNsaWRlciB0cmFjayBlbGVtZW50LlxuICAgKiBUaGUgdHJhY2sgaXMgdXNlZCByYXRoZXIgdGhhbiB0aGUgbmF0aXZlIGVsZW1lbnQgdG8gaWdub3JlIHRoZSBleHRyYSBzcGFjZSB0aGF0IHRoZSB0aHVtYiBjYW5cbiAgICogdGFrZSB1cC5cbiAgICovXG4gIHByaXZhdGUgX2dldFNsaWRlckRpbWVuc2lvbnMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3NsaWRlcldyYXBwZXIgPyB0aGlzLl9zbGlkZXJXcmFwcGVyLm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkgOiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIEZvY3VzZXMgdGhlIG5hdGl2ZSBlbGVtZW50LlxuICAgKiBDdXJyZW50bHkgb25seSB1c2VkIHRvIGFsbG93IGEgYmx1ciBldmVudCB0byBmaXJlIGJ1dCB3aWxsIGJlIHVzZWQgd2l0aCBrZXlib2FyZCBpbnB1dCBsYXRlci5cbiAgICovXG4gIHByaXZhdGUgX2ZvY3VzSG9zdEVsZW1lbnQoKSB7XG4gICAgdGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG4gIH1cblxuICAvKiogQmx1cnMgdGhlIG5hdGl2ZSBlbGVtZW50LiAqL1xuICBwcml2YXRlIF9ibHVySG9zdEVsZW1lbnQoKSB7XG4gICAgdGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmJsdXIoKTtcbiAgfVxuXG4gIC8qKiBSdW5zIGEgY2FsbGJhY2sgb3V0c2lkZSBvZiB0aGUgTmdab25lLCBpZiBwb3NzaWJsZS4gKi9cbiAgcHJpdmF0ZSBfcnVuT3V0c2l6ZVpvbmUoZm46ICgpID0+IGFueSkge1xuICAgIC8vIEBicmVha2luZy1jaGFuZ2UgOS4wLjAgUmVtb3ZlIHRoaXMgZnVuY3Rpb24gb25jZSBgX25nWm9uZWAgaXMgYSByZXF1aXJlZCBwYXJhbWV0ZXIuXG4gICAgdGhpcy5fbmdab25lID8gdGhpcy5fbmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKGZuKSA6IGZuKCk7XG4gIH1cblxuICAvKiogUnVucyBhIGNhbGxiYWNrIGluc2lkZSBvZiB0aGUgTmdab25lLCBpZiBwb3NzaWJsZS4gKi9cbiAgcHJpdmF0ZSBfcnVuSW5zaWRlWm9uZShmbjogKCkgPT4gYW55KSB7XG4gICAgLy8gQGJyZWFraW5nLWNoYW5nZSA5LjAuMCBSZW1vdmUgdGhpcyBmdW5jdGlvbiBvbmNlIGBfbmdab25lYCBpcyBhIHJlcXVpcmVkIHBhcmFtZXRlci5cbiAgICB0aGlzLl9uZ1pvbmUgPyB0aGlzLl9uZ1pvbmUucnVuKGZuKSA6IGZuKCk7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgbW9kZWwgdmFsdWUuIEltcGxlbWVudGVkIGFzIHBhcnQgb2YgQ29udHJvbFZhbHVlQWNjZXNzb3IuXG4gICAqIEBwYXJhbSB2YWx1ZVxuICAgKi9cbiAgd3JpdGVWYWx1ZSh2YWx1ZTogYW55KSB7XG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVycyBhIGNhbGxiYWNrIHRvIGJlIHRyaWdnZXJlZCB3aGVuIHRoZSB2YWx1ZSBoYXMgY2hhbmdlZC5cbiAgICogSW1wbGVtZW50ZWQgYXMgcGFydCBvZiBDb250cm9sVmFsdWVBY2Nlc3Nvci5cbiAgICogQHBhcmFtIGZuIENhbGxiYWNrIHRvIGJlIHJlZ2lzdGVyZWQuXG4gICAqL1xuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiAodmFsdWU6IGFueSkgPT4gdm9pZCkge1xuICAgIHRoaXMuX2NvbnRyb2xWYWx1ZUFjY2Vzc29yQ2hhbmdlRm4gPSBmbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgYSBjYWxsYmFjayB0byBiZSB0cmlnZ2VyZWQgd2hlbiB0aGUgY29tcG9uZW50IGlzIHRvdWNoZWQuXG4gICAqIEltcGxlbWVudGVkIGFzIHBhcnQgb2YgQ29udHJvbFZhbHVlQWNjZXNzb3IuXG4gICAqIEBwYXJhbSBmbiBDYWxsYmFjayB0byBiZSByZWdpc3RlcmVkLlxuICAgKi9cbiAgcmVnaXN0ZXJPblRvdWNoZWQoZm46IGFueSkge1xuICAgIHRoaXMub25Ub3VjaGVkID0gZm47XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB3aGV0aGVyIHRoZSBjb21wb25lbnQgc2hvdWxkIGJlIGRpc2FibGVkLlxuICAgKiBJbXBsZW1lbnRlZCBhcyBwYXJ0IG9mIENvbnRyb2xWYWx1ZUFjY2Vzc29yLlxuICAgKiBAcGFyYW0gaXNEaXNhYmxlZFxuICAgKi9cbiAgc2V0RGlzYWJsZWRTdGF0ZShpc0Rpc2FibGVkOiBib29sZWFuKSB7XG4gICAgdGhpcy5kaXNhYmxlZCA9IGlzRGlzYWJsZWQ7XG4gIH1cblxuICBpc1JhbmdlU2xpZGVyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnZhbHVlIGluc3RhbmNlb2YgQXJyYXk7XG4gIH1cblxuICBwcml2YXRlIGNhbGN1bGF0ZUluaXRpYWxTbGlkZURpcmVjdGlvbihldmVudDogTW91c2VFdmVudCB8IFRvdWNoRXZlbnQpIHtcbiAgICBpZiAoIXRoaXMuX3NsaWRlckRpbWVuc2lvbnMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy52ZXJ0aWNhbCA/IHRoaXMuX3NsaWRlckRpbWVuc2lvbnMudG9wIDogdGhpcy5fc2xpZGVyRGltZW5zaW9ucy5sZWZ0O1xuICAgIGNvbnN0IHNpemUgPSB0aGlzLnZlcnRpY2FsID8gdGhpcy5fc2xpZGVyRGltZW5zaW9ucy5oZWlnaHQgOiB0aGlzLl9zbGlkZXJEaW1lbnNpb25zLndpZHRoO1xuICAgIGNvbnN0IHBvaW50ZXJQb3NpdGlvbiA9IGdldFBvaW50ZXJQb3NpdGlvbk9uUGFnZShldmVudCk7XG4gICAgY29uc3QgcG9zQ29tcG9uZW50ID0gdGhpcy52ZXJ0aWNhbCA/IHBvaW50ZXJQb3NpdGlvbi55IDogcG9pbnRlclBvc2l0aW9uLng7XG5cbiAgICAvLyBUaGUgZXhhY3QgdmFsdWUgaXMgY2FsY3VsYXRlZCBmcm9tIHRoZSBldmVudCBhbmQgdXNlZCB0byBmaW5kIHRoZSBjbG9zZXN0IHNuYXAgdmFsdWUuXG4gICAgbGV0IHBlcmNlbnQgPSBOdW1iZXIodGhpcy5fY2xhbXAoKHBvc0NvbXBvbmVudCAtIG9mZnNldCkgLyBzaXplKSk7XG5cbiAgICBpZiAodGhpcy5fc2hvdWxkSW52ZXJ0TW91c2VDb29yZHMoKSkge1xuICAgICAgcGVyY2VudCA9IDEgLSBwZXJjZW50O1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIHBlcmNlbnQgPD1cbiAgICAgICh0aGlzLnBlcmNlbnQgYXMgbnVtYmVyW10pWzBdICtcbiAgICAgICAgKCh0aGlzLnBlcmNlbnQgYXMgbnVtYmVyW10pWzFdIC0gKHRoaXMucGVyY2VudCBhcyBudW1iZXJbXSlbMF0pIC8gMlxuICAgICkge1xuICAgICAgdGhpcy5fY3VycmVudFNsaWRlckRpciA9ICdsJztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fY3VycmVudFNsaWRlckRpciA9ICdyJztcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfaW52ZXJ0OiBCb29sZWFuSW5wdXQ7XG4gIHN0YXRpYyBuZ0FjY2VwdElucHV0VHlwZV9tYXg6IE51bWJlcklucHV0O1xuICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfbWluOiBOdW1iZXJJbnB1dDtcbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX3N0ZXA6IE51bWJlcklucHV0O1xuICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfdGh1bWJMYWJlbDogQm9vbGVhbklucHV0O1xuICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfdGlja0ludGVydmFsOiBOdW1iZXJJbnB1dDtcbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX3ZhbHVlOiBOdW1iZXJJbnB1dCB8IE51bWJlcklucHV0W107XG4gIHN0YXRpYyBuZ0FjY2VwdElucHV0VHlwZV92ZXJ0aWNhbDogQm9vbGVhbklucHV0O1xuICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfZGlzYWJsZWQ6IEJvb2xlYW5JbnB1dDtcbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX3RhYkluZGV4OiBOdW1iZXJJbnB1dDtcbn1cblxuLyoqIFJldHVybnMgd2hldGhlciBhbiBldmVudCBpcyBhIHRvdWNoIGV2ZW50LiAqL1xuZnVuY3Rpb24gaXNUb3VjaEV2ZW50KGV2ZW50OiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCk6IGV2ZW50IGlzIFRvdWNoRXZlbnQge1xuICAvLyBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBmb3IgZXZlcnkgcGl4ZWwgdGhhdCB0aGUgdXNlciBoYXMgZHJhZ2dlZCBzbyB3ZSBuZWVkIGl0IHRvIGJlXG4gIC8vIGFzIGZhc3QgYXMgcG9zc2libGUuIFNpbmNlIHdlIG9ubHkgYmluZCBtb3VzZSBldmVudHMgYW5kIHRvdWNoIGV2ZW50cywgd2UgY2FuIGFzc3VtZVxuICAvLyB0aGF0IGlmIHRoZSBldmVudCdzIG5hbWUgc3RhcnRzIHdpdGggYHRgLCBpdCdzIGEgdG91Y2ggZXZlbnQuXG4gIHJldHVybiBldmVudC50eXBlWzBdID09PSAndCc7XG59XG5cbi8qKiBHZXRzIHRoZSBjb29yZGluYXRlcyBvZiBhIHRvdWNoIG9yIG1vdXNlIGV2ZW50IHJlbGF0aXZlIHRvIHRoZSB2aWV3cG9ydC4gKi9cbmZ1bmN0aW9uIGdldFBvaW50ZXJQb3NpdGlvbk9uUGFnZShldmVudDogTW91c2VFdmVudCB8IFRvdWNoRXZlbnQpIHtcbiAgLy8gYHRvdWNoZXNgIHdpbGwgYmUgZW1wdHkgZm9yIHN0YXJ0L2VuZCBldmVudHMgc28gd2UgaGF2ZSB0byBmYWxsIGJhY2sgdG8gYGNoYW5nZWRUb3VjaGVzYC5cbiAgY29uc3QgcG9pbnQgPSBpc1RvdWNoRXZlbnQoZXZlbnQpID8gZXZlbnQudG91Y2hlc1swXSB8fCBldmVudC5jaGFuZ2VkVG91Y2hlc1swXSA6IGV2ZW50O1xuICByZXR1cm4geyB4OiBwb2ludC5jbGllbnRYLCB5OiBwb2ludC5jbGllbnRZIH07XG59XG4iLCI8ZGl2IGNsYXNzPVwibXR4LXNsaWRlci13cmFwcGVyXCIgI3NsaWRlcldyYXBwZXI+XG4gIDxkaXYgY2xhc3M9XCJtdHgtc2xpZGVyLXRyYWNrLXdyYXBwZXJcIj5cbiAgICA8ZGl2ICpuZ0lmPVwiaXNSYW5nZVNsaWRlcigpXCJcbiAgICAgICAgIGNsYXNzPVwibXR4LXNsaWRlci10cmFjay1iYWNrZ3JvdW5kIG10eC1zbGlkZXItdHJhY2stYmFja2dyb3VuZC1sZWZ0XCJcbiAgICAgICAgIFtuZ1N0eWxlXT1cIl90cmFja0JhY2tncm91bmRTdHlsZXNMZWZ0XCI+PC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cIm10eC1zbGlkZXItdHJhY2stYmFja2dyb3VuZCBtdHgtc2xpZGVyLXRyYWNrLWJhY2tncm91bmQtcmlnaHRcIlxuICAgICAgICAgW25nU3R5bGVdPVwiX3RyYWNrQmFja2dyb3VuZFN0eWxlc1JpZ2h0XCI+PC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cIm10eC1zbGlkZXItdHJhY2stZmlsbFwiIFtuZ0NsYXNzXT1cInsnbXR4LXJhbmdlLXNsaWRlci1maWxsJzogaXNSYW5nZVNsaWRlcigpfVwiXG4gICAgICAgICBbbmdTdHlsZV09XCJfdHJhY2tGaWxsU3R5bGVzXCI+PC9kaXY+XG4gIDwvZGl2PlxuICA8ZGl2IGNsYXNzPVwibXR4LXNsaWRlci10aWNrcy1jb250YWluZXJcIiBbbmdTdHlsZV09XCJfdGlja3NDb250YWluZXJTdHlsZXNcIj5cbiAgICA8ZGl2IGNsYXNzPVwibXR4LXNsaWRlci10aWNrc1wiIFtuZ1N0eWxlXT1cIl90aWNrc1N0eWxlc1wiPjwvZGl2PlxuICA8L2Rpdj5cbiAgPGRpdiBjbGFzcz1cIm10eC1zbGlkZXItdGh1bWItY29udGFpbmVyXCIgI2xlZnRTbGlkZXJcbiAgICAgICBbbmdTdHlsZV09XCJfdGh1bWJDb250YWluZXJTdHlsZXNMZWZ0XCI+XG4gICAgPGRpdiBjbGFzcz1cIm10eC1zbGlkZXItZm9jdXMtcmluZ1wiPjwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJtdHgtc2xpZGVyLXRodW1iIGxlZnRcIj48L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwibXR4LXNsaWRlci10aHVtYi1sYWJlbFwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJtdHgtc2xpZGVyLXRodW1iLWxhYmVsLXRleHRcIj57e2Rpc3BsYXlWYWx1ZX19PC9zcGFuPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbiAgPGRpdiAqbmdJZj1cImlzUmFuZ2VTbGlkZXIoKVwiXG4gICAgICAgY2xhc3M9XCJtdHgtc2xpZGVyLXRodW1iLWNvbnRhaW5lclwiICNyaWdodFNsaWRlclxuICAgICAgIFtuZ1N0eWxlXT1cIl90aHVtYkNvbnRhaW5lclN0eWxlc1JpZ2h0XCI+XG4gICAgPGRpdiBjbGFzcz1cIm10eC1zbGlkZXItZm9jdXMtcmluZ1wiPjwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJtdHgtc2xpZGVyLXRodW1iIHJpZ2h0XCI+PC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cIm10eC1zbGlkZXItdGh1bWItbGFiZWxcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwibXR4LXNsaWRlci10aHVtYi1sYWJlbC10ZXh0XCI+e3tkaXNwbGF5VmFsdWVSaWdodH19PC9zcGFuPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PlxuIl19
|