@pepperi-addons/ngx-lib 0.4.1-cards-list-scroll.32 → 0.4.1
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/address/address.component.d.ts +30 -30
- package/address/address.module.d.ts +15 -15
- package/address/index.d.ts +5 -5
- package/address/public-api.d.ts +2 -2
- package/attachment/attachment.component.d.ts +85 -85
- package/attachment/attachment.module.d.ts +14 -14
- package/attachment/index.d.ts +5 -5
- package/attachment/public-api.d.ts +2 -2
- package/bread-crumbs/bread-crumbs.component.d.ts +27 -27
- package/bread-crumbs/bread-crumbs.model.d.ts +11 -11
- package/bread-crumbs/bread-crumbs.module.d.ts +15 -15
- package/bread-crumbs/index.d.ts +5 -5
- package/bread-crumbs/public-api.d.ts +3 -3
- package/button/button.component.d.ts +102 -102
- package/button/button.model.d.ts +14 -14
- package/button/button.module.d.ts +13 -13
- package/button/index.d.ts +5 -5
- package/button/public-api.d.ts +3 -3
- package/carousel/carousel-item.directive.d.ts +12 -12
- package/carousel/carousel.component.d.ts +148 -148
- package/carousel/carousel.module.d.ts +8 -8
- package/carousel/index.d.ts +5 -5
- package/carousel/public-api.d.ts +3 -3
- package/checkbox/checkbox.component.d.ts +50 -50
- package/checkbox/checkbox.module.d.ts +19 -19
- package/checkbox/index.d.ts +5 -5
- package/checkbox/public-api.d.ts +2 -2
- package/chips/chips.component.d.ts +104 -93
- package/chips/chips.component.theme.scss +16 -7
- package/chips/chips.model.d.ts +14 -14
- package/chips/chips.module.d.ts +20 -20
- package/chips/chips.service.d.ts +15 -15
- package/chips/index.d.ts +5 -5
- package/chips/public-api.d.ts +3 -3
- package/color/color-picker.component.d.ts +57 -57
- package/color/color.component.d.ts +30 -30
- package/color/color.model.d.ts +1 -1
- package/color/color.module.d.ts +26 -26
- package/color/index.d.ts +5 -5
- package/color/public-api.d.ts +3 -3
- package/core/clipboard/clipboard.directive.d.ts +5 -5
- package/core/clipboard/clipboard.service.d.ts +5 -5
- package/core/clipboard/index.d.ts +1 -1
- package/core/clipboard/public-api.d.ts +2 -2
- package/core/common/directives/auto-width.directive.d.ts +19 -19
- package/core/common/directives/button-blur.directive.d.ts +9 -9
- package/core/common/directives/button-loader.directive.d.ts +26 -26
- package/core/common/directives/data-qa.directive.d.ts +11 -11
- package/core/common/directives/div-loader.directive.d.ts +21 -21
- package/core/common/directives/index.d.ts +1 -1
- package/core/common/directives/menu-blur.directive.d.ts +10 -10
- package/core/common/directives/prevent-multi-click.directive.d.ts +7 -7
- package/core/common/directives/print.directive.d.ts +75 -75
- package/core/common/directives/public-api.d.ts +8 -8
- package/core/common/index.d.ts +1 -1
- package/core/common/model/index.d.ts +1 -1
- package/core/common/model/papi.model.d.ts +2 -2
- package/core/common/model/public-api.d.ts +3 -3
- package/core/common/model/utilities.model.d.ts +5 -5
- package/core/common/model/wapi.model.d.ts +202 -202
- package/core/common/pipes/common-pipes.d.ts +57 -57
- package/core/common/pipes/date-ago.pipe.d.ts +11 -11
- package/core/common/pipes/index.d.ts +1 -1
- package/core/common/pipes/public-api.d.ts +2 -2
- package/core/common/public-api.d.ts +4 -4
- package/core/common/services/addon.service.d.ts +50 -48
- package/core/common/services/color.service.d.ts +51 -51
- package/core/common/services/cookie.service.d.ts +53 -53
- package/core/common/services/data-convertor.service.d.ts +45 -45
- package/core/common/services/file.service.d.ts +27 -27
- package/core/common/services/index.d.ts +1 -1
- package/core/common/services/jwt-helper.service.d.ts +13 -13
- package/core/common/services/public-api.d.ts +11 -11
- package/core/common/services/session.service.d.ts +18 -18
- package/core/common/services/translate.service.d.ts +12 -12
- package/core/common/services/utilities.service.d.ts +39 -39
- package/core/common/services/validator.service.d.ts +31 -31
- package/core/common/services/window-scrolling.service.d.ts +10 -10
- package/core/customization/customization.model.d.ts +277 -277
- package/core/customization/customization.service.d.ts +159 -159
- package/core/customization/index.d.ts +1 -1
- package/core/customization/public-api.d.ts +2 -2
- package/core/http/index.d.ts +1 -1
- package/core/http/interceptors/error.interceptor.d.ts +8 -8
- package/core/http/interceptors/index.d.ts +11 -11
- package/core/http/interceptors/loader.interceptor.d.ts +11 -11
- package/core/http/interceptors/profiler.interceptor.d.ts +8 -8
- package/core/http/public-api.d.ts +2 -2
- package/core/http/services/http.service.d.ts +28 -28
- package/core/http/services/loader.service.d.ts +13 -13
- package/core/index.d.ts +1 -1
- package/core/layout/index.d.ts +1 -1
- package/core/layout/layout.service.d.ts +36 -36
- package/core/layout/public-api.d.ts +2 -2
- package/core/layout/rtl.directive.d.ts +21 -21
- package/core/portal/attach.directive.d.ts +13 -13
- package/core/portal/index.d.ts +1 -1
- package/core/portal/portal.service.d.ts +12 -12
- package/core/portal/public-api.d.ts +3 -3
- package/core/portal/target.directive.d.ts +12 -12
- package/core/public-api.d.ts +7 -7
- package/core/scroll-to/index.d.ts +1 -1
- package/core/scroll-to/public-api.d.ts +1 -1
- package/core/scroll-to/scroll-to.service.d.ts +11 -11
- package/date/date.component.d.ts +70 -69
- package/date/date.model.d.ts +31 -31
- package/date/date.module.d.ts +23 -23
- package/date/index.d.ts +5 -5
- package/date/public-api.d.ts +2 -2
- package/dialog/default-dialog.component.d.ts +12 -12
- package/dialog/dialog.component.d.ts +13 -13
- package/dialog/dialog.model.d.ts +31 -31
- package/dialog/dialog.module.d.ts +18 -18
- package/dialog/dialog.service.d.ts +27 -27
- package/dialog/index.d.ts +5 -5
- package/dialog/public-api.d.ts +4 -4
- package/draggable-items/draggable-item/draggable-item.component.d.ts +11 -11
- package/draggable-items/draggable-items.component.d.ts +36 -36
- package/draggable-items/draggable-items.model.d.ts +11 -11
- package/draggable-items/draggable-items.module.d.ts +18 -18
- package/draggable-items/index.d.ts +5 -5
- package/draggable-items/public-api.d.ts +4 -4
- package/esm2020/address/address.component.mjs +108 -108
- package/esm2020/address/address.module.mjs +53 -53
- package/esm2020/address/pepperi-addons-ngx-lib-address.mjs +4 -4
- package/esm2020/address/public-api.mjs +5 -5
- package/esm2020/attachment/attachment.component.mjs +219 -219
- package/esm2020/attachment/attachment.module.mjs +49 -49
- package/esm2020/attachment/pepperi-addons-ngx-lib-attachment.mjs +4 -4
- package/esm2020/attachment/public-api.mjs +5 -5
- package/esm2020/bread-crumbs/bread-crumbs.component.mjs +84 -84
- package/esm2020/bread-crumbs/bread-crumbs.model.mjs +6 -6
- package/esm2020/bread-crumbs/bread-crumbs.module.mjs +49 -49
- package/esm2020/bread-crumbs/pepperi-addons-ngx-lib-bread-crumbs.mjs +4 -4
- package/esm2020/bread-crumbs/public-api.mjs +6 -6
- package/esm2020/button/button.component.mjs +137 -137
- package/esm2020/button/button.model.mjs +5 -5
- package/esm2020/button/button.module.mjs +45 -45
- package/esm2020/button/pepperi-addons-ngx-lib-button.mjs +4 -4
- package/esm2020/button/public-api.mjs +6 -6
- package/esm2020/carousel/carousel-item.directive.mjs +32 -32
- package/esm2020/carousel/carousel.component.mjs +736 -736
- package/esm2020/carousel/carousel.module.mjs +16 -16
- package/esm2020/carousel/pepperi-addons-ngx-lib-carousel.mjs +4 -4
- package/esm2020/carousel/public-api.mjs +7 -7
- package/esm2020/checkbox/checkbox.component.mjs +167 -167
- package/esm2020/checkbox/checkbox.module.mjs +62 -62
- package/esm2020/checkbox/pepperi-addons-ngx-lib-checkbox.mjs +4 -4
- package/esm2020/checkbox/public-api.mjs +5 -5
- package/esm2020/chips/chips.component.mjs +190 -158
- package/esm2020/chips/chips.model.mjs +1 -1
- package/esm2020/chips/chips.module.mjs +80 -80
- package/esm2020/chips/chips.service.mjs +44 -44
- package/esm2020/chips/pepperi-addons-ngx-lib-chips.mjs +4 -4
- package/esm2020/chips/public-api.mjs +6 -6
- package/esm2020/color/color-picker.component.mjs +197 -197
- package/esm2020/color/color.component.mjs +89 -89
- package/esm2020/color/color.model.mjs +1 -1
- package/esm2020/color/color.module.mjs +92 -92
- package/esm2020/color/pepperi-addons-ngx-lib-color.mjs +4 -4
- package/esm2020/color/public-api.mjs +6 -6
- package/esm2020/core/clipboard/clipboard.directive.mjs +23 -23
- package/esm2020/core/clipboard/clipboard.service.mjs +13 -13
- package/esm2020/core/clipboard/index.mjs +4 -4
- package/esm2020/core/clipboard/public-api.mjs +5 -5
- package/esm2020/core/common/directives/auto-width.directive.mjs +76 -76
- package/esm2020/core/common/directives/button-blur.directive.mjs +23 -23
- package/esm2020/core/common/directives/button-loader.directive.mjs +111 -111
- package/esm2020/core/common/directives/data-qa.directive.mjs +22 -22
- package/esm2020/core/common/directives/div-loader.directive.mjs +60 -60
- package/esm2020/core/common/directives/index.mjs +4 -4
- package/esm2020/core/common/directives/menu-blur.directive.mjs +31 -31
- package/esm2020/core/common/directives/prevent-multi-click.directive.mjs +26 -26
- package/esm2020/core/common/directives/print.directive.mjs +144 -144
- package/esm2020/core/common/directives/public-api.mjs +12 -12
- package/esm2020/core/common/index.mjs +4 -4
- package/esm2020/core/common/model/index.mjs +4 -4
- package/esm2020/core/common/model/papi.model.mjs +2 -2
- package/esm2020/core/common/model/public-api.mjs +6 -6
- package/esm2020/core/common/model/utilities.model.mjs +56 -56
- package/esm2020/core/common/model/wapi.model.mjs +156 -156
- package/esm2020/core/common/pipes/common-pipes.mjs +166 -166
- package/esm2020/core/common/pipes/date-ago.pipe.mjs +45 -45
- package/esm2020/core/common/pipes/index.mjs +4 -4
- package/esm2020/core/common/pipes/public-api.mjs +5 -5
- package/esm2020/core/common/public-api.mjs +7 -7
- package/esm2020/core/common/services/addon.service.mjs +203 -189
- package/esm2020/core/common/services/color.service.mjs +358 -358
- package/esm2020/core/common/services/cookie.service.mjs +152 -152
- package/esm2020/core/common/services/data-convertor.service.mjs +121 -121
- package/esm2020/core/common/services/file.service.mjs +212 -212
- package/esm2020/core/common/services/index.mjs +4 -4
- package/esm2020/core/common/services/jwt-helper.service.mjs +105 -105
- package/esm2020/core/common/services/public-api.mjs +14 -14
- package/esm2020/core/common/services/session.service.mjs +70 -70
- package/esm2020/core/common/services/translate.service.mjs +45 -45
- package/esm2020/core/common/services/utilities.service.mjs +301 -299
- package/esm2020/core/common/services/validator.service.mjs +271 -271
- package/esm2020/core/common/services/window-scrolling.service.mjs +31 -31
- package/esm2020/core/customization/customization.model.mjs +301 -301
- package/esm2020/core/customization/customization.service.mjs +770 -770
- package/esm2020/core/customization/index.mjs +4 -4
- package/esm2020/core/customization/public-api.mjs +5 -5
- package/esm2020/core/http/index.mjs +4 -4
- package/esm2020/core/http/interceptors/error.interceptor.mjs +26 -26
- package/esm2020/core/http/interceptors/index.mjs +23 -23
- package/esm2020/core/http/interceptors/loader.interceptor.mjs +31 -31
- package/esm2020/core/http/interceptors/profiler.interceptor.mjs +31 -31
- package/esm2020/core/http/public-api.mjs +5 -5
- package/esm2020/core/http/services/http.service.mjs +154 -154
- package/esm2020/core/http/services/loader.service.mjs +49 -49
- package/esm2020/core/index.mjs +4 -4
- package/esm2020/core/layout/index.mjs +4 -4
- package/esm2020/core/layout/layout.service.mjs +167 -167
- package/esm2020/core/layout/public-api.mjs +5 -5
- package/esm2020/core/layout/rtl.directive.mjs +43 -43
- package/esm2020/core/portal/attach.directive.mjs +26 -26
- package/esm2020/core/portal/index.mjs +4 -4
- package/esm2020/core/portal/portal.service.mjs +35 -35
- package/esm2020/core/portal/public-api.mjs +6 -6
- package/esm2020/core/portal/target.directive.mjs +23 -23
- package/esm2020/core/public-api.mjs +10 -10
- package/esm2020/core/scroll-to/index.mjs +4 -4
- package/esm2020/core/scroll-to/public-api.mjs +5 -5
- package/esm2020/core/scroll-to/scroll-to.service.mjs +83 -83
- package/esm2020/date/date.component.mjs +312 -307
- package/esm2020/date/date.model.mjs +53 -53
- package/esm2020/date/date.module.mjs +87 -87
- package/esm2020/date/pepperi-addons-ngx-lib-date.mjs +4 -4
- package/esm2020/date/public-api.mjs +5 -5
- package/esm2020/dialog/default-dialog.component.mjs +36 -36
- package/esm2020/dialog/dialog.component.mjs +35 -35
- package/esm2020/dialog/dialog.model.mjs +32 -32
- package/esm2020/dialog/dialog.module.mjs +58 -58
- package/esm2020/dialog/dialog.service.mjs +81 -81
- package/esm2020/dialog/pepperi-addons-ngx-lib-dialog.mjs +4 -4
- package/esm2020/dialog/public-api.mjs +7 -7
- package/esm2020/draggable-items/draggable-item/draggable-item.component.mjs +26 -26
- package/esm2020/draggable-items/draggable-items.component.mjs +101 -101
- package/esm2020/draggable-items/draggable-items.model.mjs +1 -1
- package/esm2020/draggable-items/draggable-items.module.mjs +59 -59
- package/esm2020/draggable-items/pepperi-addons-ngx-lib-draggable-items.mjs +4 -4
- package/esm2020/draggable-items/public-api.mjs +7 -7
- package/esm2020/field-title/field-title.component.mjs +44 -44
- package/esm2020/field-title/field-title.module.mjs +46 -46
- package/esm2020/field-title/pepperi-addons-ngx-lib-field-title.mjs +4 -4
- package/esm2020/field-title/public-api.mjs +5 -5
- package/esm2020/files-uploader/files-uploader.component.mjs +240 -240
- package/esm2020/files-uploader/files-uploader.module.mjs +78 -78
- package/esm2020/files-uploader/pepperi-addons-ngx-lib-files-uploader.mjs +4 -4
- package/esm2020/files-uploader/public-api.mjs +5 -5
- package/esm2020/form/field-generator.component.mjs +152 -152
- package/esm2020/form/form.component.mjs +1237 -1227
- package/esm2020/form/form.model.mjs +1 -1
- package/esm2020/form/form.module.mjs +178 -178
- package/esm2020/form/indicators.component.mjs +22 -22
- package/esm2020/form/internal-button.component.mjs +183 -183
- package/esm2020/form/internal-carusel.component.mjs +116 -116
- package/esm2020/form/internal-carusel.service.mjs +31 -31
- package/esm2020/form/internal-field-generator.component.mjs +145 -145
- package/esm2020/form/internal-form.component.mjs +1215 -1215
- package/esm2020/form/internal-list.component.mjs +512 -512
- package/esm2020/form/internal-menu.component.mjs +65 -65
- package/esm2020/form/internal-page.component.mjs +361 -361
- package/esm2020/form/internal-page.service.mjs +119 -119
- package/esm2020/form/pepperi-addons-ngx-lib-form.mjs +4 -4
- package/esm2020/form/public-api.mjs +6 -6
- package/esm2020/group-buttons/group-buttons.component.mjs +70 -70
- package/esm2020/group-buttons/group-buttons.module.mjs +58 -58
- package/esm2020/group-buttons/pepperi-addons-ngx-lib-group-buttons.mjs +4 -4
- package/esm2020/group-buttons/public-api.mjs +5 -5
- package/esm2020/icon/icon-generated-all.model.mjs +117 -114
- package/esm2020/icon/icon-generated.model.mjs +454 -442
- package/esm2020/icon/icon-registry.service.mjs +24 -24
- package/esm2020/icon/icon.component.mjs +90 -90
- package/esm2020/icon/icon.module.mjs +19 -19
- package/esm2020/icon/icon.service.mjs +30 -30
- package/esm2020/icon/pepperi-addons-ngx-lib-icon.mjs +4 -4
- package/esm2020/icon/public-api.mjs +10 -10
- package/esm2020/image/image.component.mjs +246 -246
- package/esm2020/image/image.module.mjs +73 -73
- package/esm2020/image/image.service.mjs +51 -51
- package/esm2020/image/pepperi-addons-ngx-lib-image.mjs +4 -4
- package/esm2020/image/public-api.mjs +6 -6
- package/esm2020/images-filmstrip/images-filmstrip.component.mjs +336 -336
- package/esm2020/images-filmstrip/images-filmstrip.module.mjs +82 -82
- package/esm2020/images-filmstrip/pepperi-addons-ngx-lib-images-filmstrip.mjs +4 -4
- package/esm2020/images-filmstrip/public-api.mjs +5 -5
- package/esm2020/link/link.component.mjs +324 -324
- package/esm2020/link/link.module.mjs +79 -79
- package/esm2020/link/link.pipes.mjs +17 -17
- package/esm2020/link/pepperi-addons-ngx-lib-link.mjs +4 -4
- package/esm2020/link/public-api.mjs +7 -6
- package/esm2020/list/list-actions.component.mjs +43 -43
- package/esm2020/list/list-carousel.component.mjs +106 -106
- package/esm2020/list/list-chooser.component.mjs +63 -63
- package/esm2020/list/list-pager.component.mjs +119 -119
- package/esm2020/list/list-sorting.component.mjs +60 -60
- package/esm2020/list/list-total.component.mjs +29 -29
- package/esm2020/list/list-views.component.mjs +84 -84
- package/esm2020/list/list.component.mjs +1193 -1187
- package/esm2020/list/list.model.mjs +3 -3
- package/esm2020/list/list.module.mjs +143 -143
- package/esm2020/list/list.pipes.mjs +46 -46
- package/esm2020/list/pepperi-addons-ngx-lib-list.mjs +4 -4
- package/esm2020/list/public-api.mjs +14 -14
- package/esm2020/list/virtual-scroller.mjs +1070 -1070
- package/esm2020/menu/menu-item.component.mjs +114 -114
- package/esm2020/menu/menu.component.mjs +212 -212
- package/esm2020/menu/menu.model.mjs +18 -18
- package/esm2020/menu/menu.module.mjs +58 -58
- package/esm2020/menu/pepperi-addons-ngx-lib-menu.mjs +4 -4
- package/esm2020/menu/public-api.mjs +6 -6
- package/esm2020/ngx-lib.module.mjs +161 -161
- package/esm2020/page-layout/page-layout.component.mjs +34 -34
- package/esm2020/page-layout/page-layout.module.mjs +33 -33
- package/esm2020/page-layout/pepperi-addons-ngx-lib-page-layout.mjs +4 -4
- package/esm2020/page-layout/public-api.mjs +5 -5
- package/esm2020/pepperi-addons-ngx-lib.mjs +4 -4
- package/esm2020/profile-data-views-list/pepperi-addons-ngx-lib-profile-data-views-list.mjs +4 -4
- package/esm2020/profile-data-views-list/profile-data-view/profile-data-view.component.mjs +44 -44
- package/esm2020/profile-data-views-list/profile-data-views-card/profile-data-views-card.component.mjs +64 -64
- package/esm2020/profile-data-views-list/profile-data-views-list.component.mjs +94 -94
- package/esm2020/profile-data-views-list/profile-data-views-list.model.mjs +1 -1
- package/esm2020/profile-data-views-list/profile-data-views-list.module.mjs +87 -87
- package/esm2020/profile-data-views-list/public-api.mjs +8 -8
- package/esm2020/public-api.mjs +5 -5
- package/esm2020/quantity-selector/pepperi-addons-ngx-lib-quantity-selector.mjs +4 -4
- package/esm2020/quantity-selector/public-api.mjs +5 -5
- package/esm2020/quantity-selector/quantity-selector-validation.directive.mjs +48 -48
- package/esm2020/quantity-selector/quantity-selector.component.mjs +574 -574
- package/esm2020/quantity-selector/quantity-selector.module.mjs +81 -81
- package/esm2020/quantity-selector/quantity-selector.pipes.mjs +22 -22
- package/esm2020/query-builder/common/model/field.mjs +1 -1
- package/esm2020/query-builder/common/model/filter.mjs +1 -1
- package/esm2020/query-builder/common/model/legacy.mjs +1 -1
- package/esm2020/query-builder/common/model/operator-unit.mjs +41 -41
- package/esm2020/query-builder/common/model/operator.mjs +265 -265
- package/esm2020/query-builder/common/model/structure.mjs +1 -1
- package/esm2020/query-builder/common/model/type-map.mjs +27 -27
- package/esm2020/query-builder/common/model/type.mjs +5 -5
- package/esm2020/query-builder/common/services/output-query.service.mjs +113 -113
- package/esm2020/query-builder/common/services/query-structure.service.mjs +225 -225
- package/esm2020/query-builder/common/services/type-convertor.service.mjs +41 -41
- package/esm2020/query-builder/pepperi-addons-ngx-lib-query-builder.mjs +4 -4
- package/esm2020/query-builder/public-api.mjs +8 -8
- package/esm2020/query-builder/query-builder-item/query-builder-item.component.mjs +124 -124
- package/esm2020/query-builder/query-builder-section/query-builder-section.component.mjs +70 -70
- package/esm2020/query-builder/query-builder.component.mjs +109 -109
- package/esm2020/query-builder/query-builder.module.mjs +58 -58
- package/esm2020/query-builder/query-builder.service.mjs +101 -101
- package/esm2020/remote-loader/addon-block-loader.component.mjs +101 -101
- package/esm2020/remote-loader/addon-block-loader.service.mjs +61 -61
- package/esm2020/remote-loader/pepperi-addons-ngx-lib-remote-loader.mjs +4 -4
- package/esm2020/remote-loader/public-api.mjs +10 -10
- package/esm2020/remote-loader/remote-loader-element.component.mjs +112 -105
- package/esm2020/remote-loader/remote-loader.component.mjs +108 -108
- package/esm2020/remote-loader/remote-loader.model.mjs +1 -1
- package/esm2020/remote-loader/remote-loader.module.mjs +68 -68
- package/esm2020/remote-loader/remote-loader.service.mjs +80 -80
- package/esm2020/rich-html-textarea/pepperi-addons-ngx-lib-rich-html-textarea.mjs +4 -4
- package/esm2020/rich-html-textarea/public-api.mjs +5 -5
- package/esm2020/rich-html-textarea/rich-html-textarea.component.mjs +247 -247
- package/esm2020/rich-html-textarea/rich-html-textarea.module.mjs +94 -94
- package/esm2020/search/pepperi-addons-ngx-lib-search.mjs +4 -4
- package/esm2020/search/public-api.mjs +6 -6
- package/esm2020/search/search.component.mjs +316 -316
- package/esm2020/search/search.model.mjs +1 -1
- package/esm2020/search/search.module.mjs +69 -69
- package/esm2020/select/pepperi-addons-ngx-lib-select.mjs +4 -4
- package/esm2020/select/public-api.mjs +5 -5
- package/esm2020/select/select.component.mjs +263 -263
- package/esm2020/select/select.module.mjs +69 -69
- package/esm2020/select-panel/pepperi-addons-ngx-lib-select-panel.mjs +4 -4
- package/esm2020/select-panel/public-api.mjs +6 -6
- package/esm2020/select-panel/select-panel.component.mjs +158 -158
- package/esm2020/select-panel/select-panel.model.mjs +1 -1
- package/esm2020/select-panel/select-panel.module.mjs +69 -69
- package/esm2020/separator/pepperi-addons-ngx-lib-separator.mjs +4 -4
- package/esm2020/separator/public-api.mjs +5 -5
- package/esm2020/separator/separator.component.mjs +62 -62
- package/esm2020/separator/separator.module.mjs +17 -17
- package/esm2020/side-bar/pepperi-addons-ngx-lib-side-bar.mjs +4 -4
- package/esm2020/side-bar/public-api.mjs +6 -6
- package/esm2020/side-bar/side-bar.component.mjs +121 -121
- package/esm2020/side-bar/side-bar.model.mjs +1 -1
- package/esm2020/side-bar/side-bar.module.mjs +54 -54
- package/esm2020/signature/pepperi-addons-ngx-lib-signature.mjs +4 -4
- package/esm2020/signature/public-api.mjs +5 -5
- package/esm2020/signature/signature.component.mjs +253 -253
- package/esm2020/signature/signature.module.mjs +89 -89
- package/esm2020/size-detector/pepperi-addons-ngx-lib-size-detector.mjs +4 -4
- package/esm2020/size-detector/public-api.mjs +5 -5
- package/esm2020/size-detector/size-detector.component.mjs +91 -91
- package/esm2020/size-detector/size-detector.module.mjs +34 -34
- package/esm2020/slider/pepperi-addons-ngx-lib-slider.mjs +4 -4
- package/esm2020/slider/public-api.mjs +5 -5
- package/esm2020/slider/slider.component.mjs +100 -100
- package/esm2020/slider/slider.module.mjs +41 -41
- package/esm2020/smart-filters/boolean-filter/boolean-filter.component.mjs +75 -75
- package/esm2020/smart-filters/common/filter-actions.component.mjs +28 -28
- package/esm2020/smart-filters/common/model/base-filter-component.mjs +295 -295
- package/esm2020/smart-filters/common/model/creator.mjs +75 -75
- package/esm2020/smart-filters/common/model/field.mjs +116 -116
- package/esm2020/smart-filters/common/model/filter.mjs +1 -1
- package/esm2020/smart-filters/common/model/operator.mjs +270 -270
- package/esm2020/smart-filters/common/model/type.mjs +1 -1
- package/esm2020/smart-filters/date-filter/date-filter.component.mjs +181 -181
- package/esm2020/smart-filters/multi-select-filter/multi-select-filter.component.mjs +199 -199
- package/esm2020/smart-filters/number-filter/number-filter.component.mjs +135 -135
- package/esm2020/smart-filters/pepperi-addons-ngx-lib-smart-filters.mjs +4 -4
- package/esm2020/smart-filters/public-api.mjs +18 -18
- package/esm2020/smart-filters/smart-filters.component.mjs +140 -140
- package/esm2020/smart-filters/smart-filters.module.mjs +157 -157
- package/esm2020/smart-filters/text-filter/text-filter.component.mjs +92 -92
- package/esm2020/snack-bar/default-snack-bar.component.mjs +28 -28
- package/esm2020/snack-bar/pepperi-addons-ngx-lib-snack-bar.mjs +4 -4
- package/esm2020/snack-bar/public-api.mjs +7 -7
- package/esm2020/snack-bar/snack-bar.component.mjs +25 -25
- package/esm2020/snack-bar/snack-bar.model.mjs +6 -6
- package/esm2020/snack-bar/snack-bar.module.mjs +62 -62
- package/esm2020/snack-bar/snack-bar.service.mjs +59 -59
- package/esm2020/textarea/pepperi-addons-ngx-lib-textarea.mjs +4 -4
- package/esm2020/textarea/public-api.mjs +5 -5
- package/esm2020/textarea/textarea.component.mjs +187 -187
- package/esm2020/textarea/textarea.module.mjs +81 -81
- package/esm2020/textbox/pepperi-addons-ngx-lib-textbox.mjs +4 -4
- package/esm2020/textbox/public-api.mjs +5 -5
- package/esm2020/textbox/textbox-validation.directive.mjs +92 -92
- package/esm2020/textbox/textbox.component.mjs +576 -551
- package/esm2020/textbox/textbox.module.mjs +71 -71
- package/esm2020/textbox-icon/pepperi-addons-ngx-lib-textbox-icon.mjs +4 -4
- package/esm2020/textbox-icon/public-api.mjs +5 -5
- package/esm2020/textbox-icon/textbox-icon.component.mjs +47 -47
- package/esm2020/textbox-icon/textbox-icon.module.mjs +63 -63
- package/esm2020/top-bar/pepperi-addons-ngx-lib-top-bar.mjs +4 -4
- package/esm2020/top-bar/public-api.mjs +6 -6
- package/esm2020/top-bar/top-bar.component.mjs +111 -111
- package/esm2020/top-bar/top-bar.model.mjs +1 -1
- package/esm2020/top-bar/top-bar.module.mjs +61 -61
- package/fesm2015/pepperi-addons-ngx-lib-address.mjs +143 -143
- package/fesm2015/pepperi-addons-ngx-lib-attachment.mjs +253 -253
- package/fesm2015/pepperi-addons-ngx-lib-bread-crumbs.mjs +122 -122
- package/fesm2015/pepperi-addons-ngx-lib-button.mjs +171 -171
- package/fesm2015/pepperi-addons-ngx-lib-carousel.mjs +780 -780
- package/fesm2015/pepperi-addons-ngx-lib-checkbox.mjs +206 -206
- package/fesm2015/pepperi-addons-ngx-lib-chips.mjs +289 -258
- package/fesm2015/pepperi-addons-ngx-lib-chips.mjs.map +1 -1
- package/fesm2015/pepperi-addons-ngx-lib-color.mjs +336 -336
- package/fesm2015/pepperi-addons-ngx-lib-date.mjs +414 -409
- package/fesm2015/pepperi-addons-ngx-lib-date.mjs.map +1 -1
- package/fesm2015/pepperi-addons-ngx-lib-dialog.mjs +207 -207
- package/fesm2015/pepperi-addons-ngx-lib-draggable-items.mjs +163 -163
- package/fesm2015/pepperi-addons-ngx-lib-field-title.mjs +76 -76
- package/fesm2015/pepperi-addons-ngx-lib-files-uploader.mjs +291 -291
- package/fesm2015/pepperi-addons-ngx-lib-form.mjs +4129 -4119
- package/fesm2015/pepperi-addons-ngx-lib-form.mjs.map +1 -1
- package/fesm2015/pepperi-addons-ngx-lib-group-buttons.mjs +109 -109
- package/fesm2015/pepperi-addons-ngx-lib-icon.mjs +718 -703
- package/fesm2015/pepperi-addons-ngx-lib-icon.mjs.map +1 -1
- package/fesm2015/pepperi-addons-ngx-lib-image.mjs +340 -340
- package/fesm2015/pepperi-addons-ngx-lib-images-filmstrip.mjs +390 -390
- package/fesm2015/pepperi-addons-ngx-lib-link.mjs +388 -388
- package/fesm2015/pepperi-addons-ngx-lib-link.mjs.map +1 -1
- package/fesm2015/pepperi-addons-ngx-lib-list.mjs +2866 -2859
- package/fesm2015/pepperi-addons-ngx-lib-list.mjs.map +1 -1
- package/fesm2015/pepperi-addons-ngx-lib-menu.mjs +368 -368
- package/fesm2015/pepperi-addons-ngx-lib-page-layout.mjs +59 -59
- package/fesm2015/pepperi-addons-ngx-lib-profile-data-views-list.mjs +254 -254
- package/fesm2015/pepperi-addons-ngx-lib-quantity-selector.mjs +686 -686
- package/fesm2015/pepperi-addons-ngx-lib-query-builder.mjs +1119 -1119
- package/fesm2015/pepperi-addons-ngx-lib-query-builder.mjs.map +1 -1
- package/fesm2015/pepperi-addons-ngx-lib-remote-loader.mjs +511 -504
- package/fesm2015/pepperi-addons-ngx-lib-remote-loader.mjs.map +1 -1
- package/fesm2015/pepperi-addons-ngx-lib-rich-html-textarea.mjs +303 -303
- package/fesm2015/pepperi-addons-ngx-lib-rich-html-textarea.mjs.map +1 -1
- package/fesm2015/pepperi-addons-ngx-lib-search.mjs +356 -356
- package/fesm2015/pepperi-addons-ngx-lib-select-panel.mjs +206 -206
- package/fesm2015/pepperi-addons-ngx-lib-select.mjs +305 -305
- package/fesm2015/pepperi-addons-ngx-lib-separator.mjs +73 -73
- package/fesm2015/pepperi-addons-ngx-lib-side-bar.mjs +158 -158
- package/fesm2015/pepperi-addons-ngx-lib-signature.mjs +311 -311
- package/fesm2015/pepperi-addons-ngx-lib-size-detector.mjs +114 -114
- package/fesm2015/pepperi-addons-ngx-lib-slider.mjs +130 -130
- package/fesm2015/pepperi-addons-ngx-lib-smart-filters.mjs +1634 -1634
- package/fesm2015/pepperi-addons-ngx-lib-smart-filters.mjs.map +1 -1
- package/fesm2015/pepperi-addons-ngx-lib-snack-bar.mjs +152 -152
- package/fesm2015/pepperi-addons-ngx-lib-textarea.mjs +238 -238
- package/fesm2015/pepperi-addons-ngx-lib-textarea.mjs.map +1 -1
- package/fesm2015/pepperi-addons-ngx-lib-textbox-icon.mjs +95 -95
- package/fesm2015/pepperi-addons-ngx-lib-textbox.mjs +703 -678
- package/fesm2015/pepperi-addons-ngx-lib-textbox.mjs.map +1 -1
- package/fesm2015/pepperi-addons-ngx-lib-top-bar.mjs +155 -155
- package/fesm2015/pepperi-addons-ngx-lib.mjs +4632 -4616
- package/fesm2015/pepperi-addons-ngx-lib.mjs.map +1 -1
- package/fesm2020/pepperi-addons-ngx-lib-address.mjs +143 -143
- package/fesm2020/pepperi-addons-ngx-lib-attachment.mjs +253 -253
- package/fesm2020/pepperi-addons-ngx-lib-bread-crumbs.mjs +122 -122
- package/fesm2020/pepperi-addons-ngx-lib-button.mjs +171 -171
- package/fesm2020/pepperi-addons-ngx-lib-carousel.mjs +776 -776
- package/fesm2020/pepperi-addons-ngx-lib-checkbox.mjs +206 -206
- package/fesm2020/pepperi-addons-ngx-lib-chips.mjs +288 -257
- package/fesm2020/pepperi-addons-ngx-lib-chips.mjs.map +1 -1
- package/fesm2020/pepperi-addons-ngx-lib-color.mjs +333 -333
- package/fesm2020/pepperi-addons-ngx-lib-date.mjs +410 -405
- package/fesm2020/pepperi-addons-ngx-lib-date.mjs.map +1 -1
- package/fesm2020/pepperi-addons-ngx-lib-dialog.mjs +203 -203
- package/fesm2020/pepperi-addons-ngx-lib-draggable-items.mjs +162 -162
- package/fesm2020/pepperi-addons-ngx-lib-field-title.mjs +76 -76
- package/fesm2020/pepperi-addons-ngx-lib-files-uploader.mjs +288 -288
- package/fesm2020/pepperi-addons-ngx-lib-form.mjs +4128 -4118
- package/fesm2020/pepperi-addons-ngx-lib-form.mjs.map +1 -1
- package/fesm2020/pepperi-addons-ngx-lib-group-buttons.mjs +109 -109
- package/fesm2020/pepperi-addons-ngx-lib-icon.mjs +716 -701
- package/fesm2020/pepperi-addons-ngx-lib-icon.mjs.map +1 -1
- package/fesm2020/pepperi-addons-ngx-lib-image.mjs +338 -338
- package/fesm2020/pepperi-addons-ngx-lib-images-filmstrip.mjs +387 -387
- package/fesm2020/pepperi-addons-ngx-lib-link.mjs +388 -388
- package/fesm2020/pepperi-addons-ngx-lib-link.mjs.map +1 -1
- package/fesm2020/pepperi-addons-ngx-lib-list.mjs +2853 -2846
- package/fesm2020/pepperi-addons-ngx-lib-list.mjs.map +1 -1
- package/fesm2020/pepperi-addons-ngx-lib-menu.mjs +368 -368
- package/fesm2020/pepperi-addons-ngx-lib-page-layout.mjs +59 -59
- package/fesm2020/pepperi-addons-ngx-lib-profile-data-views-list.mjs +253 -253
- package/fesm2020/pepperi-addons-ngx-lib-quantity-selector.mjs +685 -685
- package/fesm2020/pepperi-addons-ngx-lib-query-builder.mjs +1108 -1108
- package/fesm2020/pepperi-addons-ngx-lib-query-builder.mjs.map +1 -1
- package/fesm2020/pepperi-addons-ngx-lib-remote-loader.mjs +489 -482
- package/fesm2020/pepperi-addons-ngx-lib-remote-loader.mjs.map +1 -1
- package/fesm2020/pepperi-addons-ngx-lib-rich-html-textarea.mjs +303 -303
- package/fesm2020/pepperi-addons-ngx-lib-rich-html-textarea.mjs.map +1 -1
- package/fesm2020/pepperi-addons-ngx-lib-search.mjs +355 -355
- package/fesm2020/pepperi-addons-ngx-lib-select-panel.mjs +205 -205
- package/fesm2020/pepperi-addons-ngx-lib-select.mjs +305 -305
- package/fesm2020/pepperi-addons-ngx-lib-separator.mjs +73 -73
- package/fesm2020/pepperi-addons-ngx-lib-side-bar.mjs +158 -158
- package/fesm2020/pepperi-addons-ngx-lib-signature.mjs +311 -311
- package/fesm2020/pepperi-addons-ngx-lib-size-detector.mjs +114 -114
- package/fesm2020/pepperi-addons-ngx-lib-slider.mjs +129 -129
- package/fesm2020/pepperi-addons-ngx-lib-smart-filters.mjs +1627 -1627
- package/fesm2020/pepperi-addons-ngx-lib-smart-filters.mjs.map +1 -1
- package/fesm2020/pepperi-addons-ngx-lib-snack-bar.mjs +149 -149
- package/fesm2020/pepperi-addons-ngx-lib-textarea.mjs +237 -237
- package/fesm2020/pepperi-addons-ngx-lib-textarea.mjs.map +1 -1
- package/fesm2020/pepperi-addons-ngx-lib-textbox-icon.mjs +95 -95
- package/fesm2020/pepperi-addons-ngx-lib-textbox.mjs +703 -678
- package/fesm2020/pepperi-addons-ngx-lib-textbox.mjs.map +1 -1
- package/fesm2020/pepperi-addons-ngx-lib-top-bar.mjs +154 -154
- package/fesm2020/pepperi-addons-ngx-lib.mjs +4602 -4586
- package/fesm2020/pepperi-addons-ngx-lib.mjs.map +1 -1
- package/field-title/field-title.component.d.ts +15 -15
- package/field-title/field-title.module.d.ts +15 -15
- package/field-title/index.d.ts +5 -5
- package/field-title/public-api.d.ts +2 -2
- package/files-uploader/files-uploader.component.d.ts +57 -57
- package/files-uploader/files-uploader.module.d.ts +21 -21
- package/files-uploader/index.d.ts +5 -5
- package/files-uploader/public-api.d.ts +2 -2
- package/form/field-generator.component.d.ts +37 -37
- package/form/form.component.d.ts +93 -93
- package/form/form.model.d.ts +20 -20
- package/form/form.module.d.ts +50 -50
- package/form/index.d.ts +5 -5
- package/form/indicators.component.d.ts +10 -10
- package/form/internal-button.component.d.ts +42 -42
- package/form/internal-carusel.component.d.ts +39 -39
- package/form/internal-carusel.service.d.ts +10 -10
- package/form/internal-field-generator.component.d.ts +33 -33
- package/form/internal-form.component.d.ts +89 -89
- package/form/internal-list.component.d.ts +95 -95
- package/form/internal-menu.component.d.ts +19 -19
- package/form/internal-page.component.d.ts +73 -73
- package/form/internal-page.service.d.ts +22 -22
- package/form/public-api.d.ts +3 -3
- package/group-buttons/group-buttons.component.d.ts +24 -24
- package/group-buttons/group-buttons.module.d.ts +18 -18
- package/group-buttons/index.d.ts +5 -5
- package/group-buttons/public-api.d.ts +2 -2
- package/icon/icon-generated-all.model.d.ts +115 -112
- package/icon/icon-generated.model.d.ts +458 -446
- package/icon/icon-registry.service.d.ts +9 -9
- package/icon/icon.component.d.ts +49 -49
- package/icon/icon.module.d.ts +7 -7
- package/icon/icon.service.d.ts +13 -13
- package/icon/index.d.ts +5 -5
- package/icon/public-api.d.ts +6 -6
- package/image/image.component.d.ts +66 -66
- package/image/image.module.d.ts +20 -20
- package/image/image.service.d.ts +14 -14
- package/image/index.d.ts +5 -5
- package/image/public-api.d.ts +3 -3
- package/images-filmstrip/images-filmstrip.component.d.ts +87 -87
- package/images-filmstrip/images-filmstrip.module.d.ts +22 -22
- package/images-filmstrip/index.d.ts +5 -5
- package/images-filmstrip/public-api.d.ts +2 -2
- package/index.d.ts +5 -5
- package/link/index.d.ts +5 -5
- package/link/link.component.d.ts +125 -125
- package/link/link.module.d.ts +22 -22
- package/link/link.pipes.d.ts +7 -7
- package/link/public-api.d.ts +3 -2
- package/list/index.d.ts +5 -5
- package/list/list-actions.component.d.ts +18 -18
- package/list/list-carousel.component.d.ts +40 -40
- package/list/list-chooser.component.d.ts +29 -29
- package/list/list-pager.component.d.ts +39 -39
- package/list/list-sorting.component.d.ts +30 -30
- package/list/list-total.component.d.ts +11 -11
- package/list/list-views.component.d.ts +35 -35
- package/list/list.component.d.ts +167 -165
- package/list/list.model.d.ts +31 -31
- package/list/list.module.d.ts +34 -34
- package/list/list.pipes.d.ts +16 -16
- package/list/public-api.d.ts +10 -10
- package/list/virtual-scroller.d.ts +183 -183
- package/menu/index.d.ts +5 -5
- package/menu/menu-item.component.d.ts +28 -28
- package/menu/menu.component.d.ts +48 -48
- package/menu/menu.model.d.ts +25 -25
- package/menu/menu.module.d.ts +18 -18
- package/menu/public-api.d.ts +3 -3
- package/ngx-lib.module.d.ts +24 -24
- package/package.json +1 -1
- package/page-layout/index.d.ts +5 -5
- package/page-layout/page-layout.component.d.ts +19 -19
- package/page-layout/page-layout.module.d.ts +10 -10
- package/page-layout/public-api.d.ts +2 -2
- package/profile-data-views-list/index.d.ts +5 -5
- package/profile-data-views-list/profile-data-view/profile-data-view.component.d.ts +18 -18
- package/profile-data-views-list/profile-data-views-card/profile-data-views-card.component.d.ts +24 -24
- package/profile-data-views-list/profile-data-views-list.component.d.ts +35 -35
- package/profile-data-views-list/profile-data-views-list.model.d.ts +18 -18
- package/profile-data-views-list/profile-data-views-list.module.d.ts +23 -23
- package/profile-data-views-list/public-api.d.ts +5 -5
- package/public-api.d.ts +2 -2
- package/quantity-selector/index.d.ts +5 -5
- package/quantity-selector/public-api.d.ts +2 -2
- package/quantity-selector/quantity-selector-validation.directive.d.ts +17 -17
- package/quantity-selector/quantity-selector.component.d.ts +112 -112
- package/quantity-selector/quantity-selector.module.d.ts +23 -23
- package/quantity-selector/quantity-selector.pipes.d.ts +7 -7
- package/query-builder/common/model/field.d.ts +8 -8
- package/query-builder/common/model/filter.d.ts +6 -6
- package/query-builder/common/model/legacy.d.ts +29 -29
- package/query-builder/common/model/operator-unit.d.ts +13 -13
- package/query-builder/common/model/operator.d.ts +21 -21
- package/query-builder/common/model/structure.d.ts +4 -4
- package/query-builder/common/model/type-map.d.ts +12 -12
- package/query-builder/common/model/type.d.ts +4 -4
- package/query-builder/common/services/output-query.service.d.ts +47 -47
- package/query-builder/common/services/query-structure.service.d.ts +82 -82
- package/query-builder/common/services/type-convertor.service.d.ts +13 -13
- package/query-builder/index.d.ts +5 -5
- package/query-builder/public-api.d.ts +5 -5
- package/query-builder/query-builder-item/query-builder-item.component.d.ts +41 -41
- package/query-builder/query-builder-section/query-builder-section.component.d.ts +30 -30
- package/query-builder/query-builder.component.d.ts +39 -39
- package/query-builder/query-builder.module.d.ts +16 -16
- package/query-builder/query-builder.service.d.ts +30 -30
- package/remote-loader/addon-block-loader.component.d.ts +36 -36
- package/remote-loader/addon-block-loader.service.d.ts +15 -15
- package/remote-loader/index.d.ts +5 -5
- package/remote-loader/public-api.d.ts +7 -7
- package/remote-loader/remote-loader-element.component.d.ts +32 -30
- package/remote-loader/remote-loader.component.d.ts +25 -25
- package/remote-loader/remote-loader.model.d.ts +41 -41
- package/remote-loader/remote-loader.module.d.ts +15 -15
- package/remote-loader/remote-loader.service.d.ts +15 -15
- package/rich-html-textarea/index.d.ts +5 -5
- package/rich-html-textarea/public-api.d.ts +2 -2
- package/rich-html-textarea/rich-html-textarea.component.d.ts +79 -79
- package/rich-html-textarea/rich-html-textarea.module.d.ts +25 -25
- package/search/index.d.ts +5 -5
- package/search/public-api.d.ts +3 -3
- package/search/search.component.d.ts +65 -65
- package/search/search.model.d.ts +14 -14
- package/search/search.module.d.ts +20 -20
- package/select/index.d.ts +5 -5
- package/select/public-api.d.ts +2 -2
- package/select/select.component.d.ts +59 -59
- package/select/select.module.d.ts +20 -20
- package/select-panel/index.d.ts +5 -5
- package/select-panel/public-api.d.ts +3 -3
- package/select-panel/select-panel.component.d.ts +51 -51
- package/select-panel/select-panel.model.d.ts +5 -5
- package/select-panel/select-panel.module.d.ts +19 -19
- package/separator/index.d.ts +5 -5
- package/separator/public-api.d.ts +2 -2
- package/separator/separator.component.d.ts +22 -22
- package/separator/separator.module.d.ts +8 -8
- package/side-bar/index.d.ts +5 -5
- package/side-bar/public-api.d.ts +3 -3
- package/side-bar/side-bar.component.d.ts +42 -42
- package/side-bar/side-bar.model.d.ts +4 -4
- package/side-bar/side-bar.module.d.ts +16 -16
- package/signature/index.d.ts +5 -5
- package/signature/public-api.d.ts +2 -2
- package/signature/signature.component.d.ts +68 -68
- package/signature/signature.module.d.ts +24 -24
- package/size-detector/index.d.ts +5 -5
- package/size-detector/public-api.d.ts +2 -2
- package/size-detector/size-detector.component.d.ts +29 -29
- package/size-detector/size-detector.module.d.ts +11 -11
- package/slider/index.d.ts +5 -5
- package/slider/public-api.d.ts +2 -2
- package/slider/slider.component.d.ts +39 -39
- package/slider/slider.module.d.ts +12 -12
- package/smart-filters/boolean-filter/boolean-filter.component.d.ts +28 -28
- package/smart-filters/common/filter-actions.component.d.ts +12 -12
- package/smart-filters/common/model/base-filter-component.d.ts +74 -74
- package/smart-filters/common/model/creator.d.ts +6 -6
- package/smart-filters/common/model/field.d.ts +69 -69
- package/smart-filters/common/model/filter.d.ts +11 -11
- package/smart-filters/common/model/operator.d.ts +51 -51
- package/smart-filters/common/model/type.d.ts +4 -4
- package/smart-filters/date-filter/date-filter.component.d.ts +60 -60
- package/smart-filters/index.d.ts +5 -5
- package/smart-filters/multi-select-filter/multi-select-filter.component.d.ts +56 -56
- package/smart-filters/number-filter/number-filter.component.d.ts +52 -52
- package/smart-filters/public-api.d.ts +14 -14
- package/smart-filters/smart-filters.component.d.ts +35 -35
- package/smart-filters/smart-filters.module.d.ts +37 -37
- package/smart-filters/text-filter/text-filter.component.d.ts +28 -28
- package/snack-bar/default-snack-bar.component.d.ts +13 -13
- package/snack-bar/index.d.ts +5 -5
- package/snack-bar/public-api.d.ts +4 -4
- package/snack-bar/snack-bar.component.d.ts +12 -12
- package/snack-bar/snack-bar.model.d.ts +8 -8
- package/snack-bar/snack-bar.module.d.ts +19 -19
- package/snack-bar/snack-bar.service.d.ts +24 -24
- package/src/core/style/base/typography.scss +1 -1
- package/src/core/style/components/textarea.scss +4 -2
- package/textarea/index.d.ts +5 -5
- package/textarea/public-api.d.ts +2 -2
- package/textarea/textarea.component.d.ts +56 -56
- package/textarea/textarea.module.d.ts +23 -23
- package/textbox/index.d.ts +5 -5
- package/textbox/public-api.d.ts +2 -2
- package/textbox/textbox-validation.directive.d.ts +22 -22
- package/textbox/textbox.component.d.ts +157 -154
- package/textbox/textbox.module.d.ts +22 -22
- package/textbox-icon/index.d.ts +5 -5
- package/textbox-icon/public-api.d.ts +2 -2
- package/textbox-icon/textbox-icon.component.d.ts +13 -13
- package/textbox-icon/textbox-icon.module.d.ts +16 -16
- package/theming-offline.scss +79 -0
- package/theming.scss +4 -31
- package/top-bar/index.d.ts +5 -5
- package/top-bar/public-api.d.ts +3 -3
- package/top-bar/top-bar.component.d.ts +39 -39
- package/top-bar/top-bar.model.d.ts +4 -4
- package/top-bar/top-bar.module.d.ts +18 -18
|
@@ -1,1080 +1,1080 @@
|
|
|
1
|
-
import { Component, ContentChild, ElementRef, EventEmitter, Inject, Input, NgModule, Optional, Output, ViewChild, } from '@angular/core';
|
|
2
|
-
import { PLATFORM_ID } from '@angular/core';
|
|
3
|
-
import { isPlatformServer } from '@angular/common';
|
|
4
|
-
import { CommonModule } from '@angular/common';
|
|
5
|
-
import * as tween from '@tweenjs/tween.js';
|
|
6
|
-
import * as i0 from "@angular/core";
|
|
7
|
-
export function VIRTUAL_SCROLLER_DEFAULT_OPTIONS_FACTORY() {
|
|
8
|
-
return {
|
|
9
|
-
checkResizeInterval: 1000,
|
|
10
|
-
modifyOverflowStyleOfParentScroll: true,
|
|
11
|
-
resizeBypassRefreshThreshold: 5,
|
|
12
|
-
scrollAnimationTime: 750,
|
|
13
|
-
scrollDebounceTime: 0,
|
|
14
|
-
scrollThrottlingTime: 0,
|
|
15
|
-
stripedTable: false
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
export class VirtualScrollerComponent {
|
|
19
|
-
constructor(element, renderer, zone, changeDetectorRef, platformId, options) {
|
|
20
|
-
this.element = element;
|
|
21
|
-
this.renderer = renderer;
|
|
22
|
-
this.zone = zone;
|
|
23
|
-
this.changeDetectorRef = changeDetectorRef;
|
|
24
|
-
this.window = window;
|
|
25
|
-
this._disable = false;
|
|
26
|
-
this.executeRefreshOutsideAngularZone = false;
|
|
27
|
-
this._enableUnequalChildrenSizes = false;
|
|
28
|
-
this.RTL = false;
|
|
29
|
-
this.useMarginInsteadOfTranslate = false;
|
|
30
|
-
this.ssrViewportWidth = 1920;
|
|
31
|
-
this.ssrViewportHeight = 1080;
|
|
32
|
-
this._items = [];
|
|
33
|
-
this.compareItems = (item1, item2) => item1 === item2;
|
|
34
|
-
// private _lastChildRect: DOMRect = null;
|
|
35
|
-
this.vsChildRectChange = new EventEmitter();
|
|
36
|
-
this.vsUpdate = new EventEmitter();
|
|
37
|
-
this.vsChange = new EventEmitter();
|
|
38
|
-
this.vsStart = new EventEmitter();
|
|
39
|
-
this.vsEnd = new EventEmitter();
|
|
40
|
-
this.calculatedScrollbarWidth = 0;
|
|
41
|
-
this.calculatedScrollbarHeight = 0;
|
|
42
|
-
this.padding = 0;
|
|
43
|
-
this.previousViewPort = {};
|
|
44
|
-
this.cachedPageSize = 0;
|
|
45
|
-
this.previousScrollNumberElements = 0;
|
|
46
|
-
this.isAngularUniversalSSR = isPlatformServer(platformId);
|
|
47
|
-
const defaultOptions = VIRTUAL_SCROLLER_DEFAULT_OPTIONS_FACTORY();
|
|
48
|
-
this.checkResizeInterval = options?.checkResizeInterval || defaultOptions.checkResizeInterval;
|
|
49
|
-
this.modifyOverflowStyleOfParentScroll = options?.modifyOverflowStyleOfParentScroll || defaultOptions.modifyOverflowStyleOfParentScroll;
|
|
50
|
-
this.resizeBypassRefreshThreshold = options?.resizeBypassRefreshThreshold || defaultOptions.resizeBypassRefreshThreshold;
|
|
51
|
-
this.scrollAnimationTime = options?.scrollAnimationTime || defaultOptions.scrollAnimationTime;
|
|
52
|
-
this.scrollDebounceTime = options?.scrollDebounceTime || defaultOptions.scrollDebounceTime;
|
|
53
|
-
this.scrollThrottlingTime = options?.scrollThrottlingTime || defaultOptions.scrollThrottlingTime;
|
|
54
|
-
this.scrollbarHeight = options?.scrollbarHeight || defaultOptions.scrollbarHeight;
|
|
55
|
-
this.scrollbarWidth = options?.scrollbarWidth || defaultOptions.scrollbarWidth;
|
|
56
|
-
this.stripedTable = options?.stripedTable || defaultOptions.stripedTable;
|
|
57
|
-
this.horizontal = false;
|
|
58
|
-
this.resetWrapGroupDimensions();
|
|
59
|
-
}
|
|
60
|
-
get viewPortInfo() {
|
|
61
|
-
const pageInfo = this.previousViewPort || {};
|
|
62
|
-
return {
|
|
63
|
-
startIndex: pageInfo.startIndex || 0,
|
|
64
|
-
endIndex: pageInfo.endIndex || 0,
|
|
65
|
-
scrollStartPosition: pageInfo.scrollStartPosition || 0,
|
|
66
|
-
scrollEndPosition: pageInfo.scrollEndPosition || 0,
|
|
67
|
-
scrollDirection: pageInfo.scrollDirection || 'forward',
|
|
68
|
-
maxScrollPosition: pageInfo.maxScrollPosition || 0,
|
|
69
|
-
startIndexWithBuffer: pageInfo.startIndexWithBuffer || 0,
|
|
70
|
-
endIndexWithBuffer: pageInfo.endIndexWithBuffer || 0,
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
get disable() {
|
|
74
|
-
return this._disable;
|
|
75
|
-
}
|
|
76
|
-
set disable(value) {
|
|
77
|
-
if (this._disable === value) {
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
this._disable = value;
|
|
81
|
-
if (this._disable) {
|
|
82
|
-
this.removeScrollEventHandlers();
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
this.addScrollEventHandlers();
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
get enableUnequalChildrenSizes() {
|
|
89
|
-
return this._enableUnequalChildrenSizes;
|
|
90
|
-
}
|
|
91
|
-
set enableUnequalChildrenSizes(value) {
|
|
92
|
-
if (this._enableUnequalChildrenSizes === value) {
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
this._enableUnequalChildrenSizes = value;
|
|
96
|
-
this.minMeasuredChildWidth = undefined;
|
|
97
|
-
this.minMeasuredChildHeight = undefined;
|
|
98
|
-
}
|
|
99
|
-
get bufferAmount() {
|
|
100
|
-
if (typeof (this._bufferAmount) === 'number' && this._bufferAmount > 0) {
|
|
101
|
-
return this._bufferAmount;
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
return this.enableUnequalChildrenSizes ? 5 : 0;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
set bufferAmount(value) {
|
|
108
|
-
this._bufferAmount = value;
|
|
109
|
-
}
|
|
110
|
-
get scrollThrottlingTime() {
|
|
111
|
-
return this._scrollThrottlingTime;
|
|
112
|
-
}
|
|
113
|
-
set scrollThrottlingTime(value) {
|
|
114
|
-
this._scrollThrottlingTime = value;
|
|
115
|
-
this.updateOnScrollFunction();
|
|
116
|
-
}
|
|
117
|
-
get scrollDebounceTime() {
|
|
118
|
-
return this._scrollDebounceTime;
|
|
119
|
-
}
|
|
120
|
-
set scrollDebounceTime(value) {
|
|
121
|
-
this._scrollDebounceTime = value;
|
|
122
|
-
this.updateOnScrollFunction();
|
|
123
|
-
}
|
|
124
|
-
updateOnScrollFunction() {
|
|
125
|
-
if (this.scrollDebounceTime) {
|
|
126
|
-
this.onScroll = this.debounce(() => {
|
|
127
|
-
this.refresh_internal(false);
|
|
128
|
-
}, this.scrollDebounceTime);
|
|
129
|
-
}
|
|
130
|
-
else if (this.scrollThrottlingTime) {
|
|
131
|
-
this.onScroll = this.throttleTrailing(() => {
|
|
132
|
-
this.refresh_internal(false);
|
|
133
|
-
}, this.scrollThrottlingTime);
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
this.onScroll = () => {
|
|
137
|
-
this.refresh_internal(false);
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
get checkResizeInterval() {
|
|
142
|
-
return this._checkResizeInterval;
|
|
143
|
-
}
|
|
144
|
-
set checkResizeInterval(value) {
|
|
145
|
-
if (this._checkResizeInterval === value) {
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
this._checkResizeInterval = value;
|
|
149
|
-
this.addScrollEventHandlers();
|
|
150
|
-
}
|
|
151
|
-
get items() {
|
|
152
|
-
return this._items;
|
|
153
|
-
}
|
|
154
|
-
set items(value) {
|
|
155
|
-
if (value === this._items) {
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
this._items = value || [];
|
|
159
|
-
this.refresh_internal(true);
|
|
160
|
-
}
|
|
161
|
-
get horizontal() {
|
|
162
|
-
return this._horizontal;
|
|
163
|
-
}
|
|
164
|
-
set horizontal(value) {
|
|
165
|
-
this._horizontal = value;
|
|
166
|
-
this.updateDirection();
|
|
167
|
-
}
|
|
168
|
-
revertParentOverscroll() {
|
|
169
|
-
const scrollElement = this.getScrollElement();
|
|
170
|
-
if (scrollElement && this.oldParentScrollOverflow) {
|
|
171
|
-
scrollElement.style['overflow-y'] = this.oldParentScrollOverflow.y;
|
|
172
|
-
scrollElement.style['overflow-x'] = this.oldParentScrollOverflow.x;
|
|
173
|
-
}
|
|
174
|
-
this.oldParentScrollOverflow = undefined;
|
|
175
|
-
}
|
|
176
|
-
get parentScroll() {
|
|
177
|
-
return this._parentScroll;
|
|
178
|
-
}
|
|
179
|
-
set parentScroll(value) {
|
|
180
|
-
if (this._parentScroll === value) {
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
this.revertParentOverscroll();
|
|
184
|
-
this._parentScroll = value;
|
|
185
|
-
this.addScrollEventHandlers();
|
|
186
|
-
const scrollElement = this.getScrollElement();
|
|
187
|
-
if (this.modifyOverflowStyleOfParentScroll && scrollElement !== this.element.nativeElement) {
|
|
188
|
-
this.oldParentScrollOverflow = { x: scrollElement.style['overflow-x'], y: scrollElement.style['overflow-y'] };
|
|
189
|
-
scrollElement.style['overflow-y'] = this.horizontal ? 'visible' : 'auto';
|
|
190
|
-
scrollElement.style['overflow-x'] = this.horizontal ? 'auto' : 'visible';
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
ngOnInit() {
|
|
194
|
-
this.addScrollEventHandlers();
|
|
195
|
-
}
|
|
196
|
-
ngOnDestroy() {
|
|
197
|
-
this.removeScrollEventHandlers();
|
|
198
|
-
this.revertParentOverscroll();
|
|
199
|
-
}
|
|
200
|
-
ngOnChanges(changes) {
|
|
201
|
-
const indexLengthChanged = this.cachedItemsLength !== this.items.length;
|
|
202
|
-
this.cachedItemsLength = this.items.length;
|
|
203
|
-
const firstRun = !changes.items || !changes.items.previousValue || changes.items.previousValue.length === 0;
|
|
204
|
-
this.refresh_internal(indexLengthChanged || firstRun);
|
|
205
|
-
}
|
|
206
|
-
ngDoCheck() {
|
|
207
|
-
if (this.cachedItemsLength !== this.items.length) {
|
|
208
|
-
this.cachedItemsLength = this.items.length;
|
|
209
|
-
this.refresh_internal(true);
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
if (this.previousViewPort && this.viewPortItems && this.viewPortItems.length > 0) {
|
|
213
|
-
let itemsArrayChanged = false;
|
|
214
|
-
for (let i = 0; i < this.viewPortItems.length; ++i) {
|
|
215
|
-
if (!this.compareItems(this.items[this.previousViewPort.startIndexWithBuffer + i], this.viewPortItems[i])) {
|
|
216
|
-
itemsArrayChanged = true;
|
|
217
|
-
break;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
if (itemsArrayChanged) {
|
|
221
|
-
this.refresh_internal(true);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
refresh(refreshCompletedCallback = undefined) {
|
|
226
|
-
this.refresh_internal(true, refreshCompletedCallback);
|
|
227
|
-
}
|
|
228
|
-
invalidateAllCachedMeasurements() {
|
|
229
|
-
this.wrapGroupDimensions = {
|
|
230
|
-
maxChildSizePerWrapGroup: [],
|
|
231
|
-
numberOfKnownWrapGroupChildSizes: 0,
|
|
232
|
-
sumOfKnownWrapGroupChildWidths: 0,
|
|
233
|
-
sumOfKnownWrapGroupChildHeights: 0
|
|
234
|
-
};
|
|
235
|
-
this.minMeasuredChildWidth = undefined;
|
|
236
|
-
this.minMeasuredChildHeight = undefined;
|
|
237
|
-
this.refresh_internal(false);
|
|
238
|
-
}
|
|
239
|
-
invalidateCachedMeasurementForItem(item) {
|
|
240
|
-
if (this.enableUnequalChildrenSizes) {
|
|
241
|
-
const index = this.items && this.items.indexOf(item);
|
|
242
|
-
if (index >= 0) {
|
|
243
|
-
this.invalidateCachedMeasurementAtIndex(index);
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
else {
|
|
247
|
-
this.minMeasuredChildWidth = undefined;
|
|
248
|
-
this.minMeasuredChildHeight = undefined;
|
|
249
|
-
}
|
|
250
|
-
this.refresh_internal(false);
|
|
251
|
-
}
|
|
252
|
-
invalidateCachedMeasurementAtIndex(index) {
|
|
253
|
-
if (this.enableUnequalChildrenSizes) {
|
|
254
|
-
const cachedMeasurement = this.wrapGroupDimensions.maxChildSizePerWrapGroup[index];
|
|
255
|
-
if (cachedMeasurement) {
|
|
256
|
-
this.wrapGroupDimensions.maxChildSizePerWrapGroup[index] = undefined;
|
|
257
|
-
--this.wrapGroupDimensions.numberOfKnownWrapGroupChildSizes;
|
|
258
|
-
this.wrapGroupDimensions.sumOfKnownWrapGroupChildWidths -= cachedMeasurement.childWidth || 0;
|
|
259
|
-
this.wrapGroupDimensions.sumOfKnownWrapGroupChildHeights -= cachedMeasurement.childHeight || 0;
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
else {
|
|
263
|
-
this.minMeasuredChildWidth = undefined;
|
|
264
|
-
this.minMeasuredChildHeight = undefined;
|
|
265
|
-
}
|
|
266
|
-
this.refresh_internal(false);
|
|
267
|
-
}
|
|
268
|
-
scrollInto(item, alignToBeginning = true, additionalOffset = 0, animationMilliseconds = undefined, animationCompletedCallback = undefined) {
|
|
269
|
-
const index = this.items.indexOf(item);
|
|
270
|
-
if (index === -1) {
|
|
271
|
-
return;
|
|
272
|
-
}
|
|
273
|
-
this.scrollToIndex(index, alignToBeginning, additionalOffset, animationMilliseconds, animationCompletedCallback);
|
|
274
|
-
}
|
|
275
|
-
scrollToIndex(index, alignToBeginning = true, additionalOffset = 0, animationMilliseconds = undefined, animationCompletedCallback = undefined) {
|
|
276
|
-
let maxRetries = 5;
|
|
277
|
-
const retryIfNeeded = () => {
|
|
278
|
-
--maxRetries;
|
|
279
|
-
if (maxRetries <= 0) {
|
|
280
|
-
if (animationCompletedCallback) {
|
|
281
|
-
animationCompletedCallback();
|
|
282
|
-
}
|
|
283
|
-
return;
|
|
284
|
-
}
|
|
285
|
-
const dimensions = this.calculateDimensions();
|
|
286
|
-
const desiredStartIndex = Math.min(Math.max(index, 0), dimensions.itemCount - 1);
|
|
287
|
-
if (this.previousViewPort.startIndex === desiredStartIndex) {
|
|
288
|
-
if (animationCompletedCallback) {
|
|
289
|
-
animationCompletedCallback();
|
|
290
|
-
}
|
|
291
|
-
return;
|
|
292
|
-
}
|
|
293
|
-
this.scrollToIndex_internal(index, alignToBeginning, additionalOffset, 0, retryIfNeeded);
|
|
294
|
-
};
|
|
295
|
-
this.scrollToIndex_internal(index, alignToBeginning, additionalOffset, animationMilliseconds, retryIfNeeded);
|
|
296
|
-
}
|
|
297
|
-
scrollToIndex_internal(index, alignToBeginning = true, additionalOffset = 0, animationMilliseconds = undefined, animationCompletedCallback = undefined) {
|
|
298
|
-
animationMilliseconds = animationMilliseconds === undefined ? this.scrollAnimationTime : animationMilliseconds;
|
|
299
|
-
const dimensions = this.calculateDimensions();
|
|
300
|
-
let scroll = this.calculatePadding(index, dimensions) + additionalOffset;
|
|
301
|
-
if (!alignToBeginning) {
|
|
302
|
-
scroll -= dimensions.wrapGroupsPerPage * dimensions[this._childScrollDim];
|
|
303
|
-
}
|
|
304
|
-
this.scrollToPosition(scroll, animationMilliseconds, animationCompletedCallback);
|
|
305
|
-
}
|
|
306
|
-
scrollToPosition(scrollPosition, animationMilliseconds = undefined, animationCompletedCallback = undefined) {
|
|
307
|
-
scrollPosition += this.getElementsOffset();
|
|
308
|
-
animationMilliseconds = animationMilliseconds === undefined ? this.scrollAnimationTime : animationMilliseconds;
|
|
309
|
-
const scrollElement = this.getScrollElement();
|
|
310
|
-
let animationRequest;
|
|
311
|
-
if (this.currentTween) {
|
|
312
|
-
this.currentTween.stop();
|
|
313
|
-
this.currentTween = undefined;
|
|
314
|
-
}
|
|
315
|
-
if (!animationMilliseconds) {
|
|
316
|
-
this.renderer.setProperty(scrollElement, this._scrollType, scrollPosition);
|
|
317
|
-
this.refresh_internal(false, animationCompletedCallback);
|
|
318
|
-
return;
|
|
319
|
-
}
|
|
320
|
-
const tweenConfigObj = { scrollPosition: scrollElement[this._scrollType] };
|
|
321
|
-
const newTween = new tween.Tween(tweenConfigObj)
|
|
322
|
-
.to({ scrollPosition }, animationMilliseconds)
|
|
323
|
-
.easing(tween.Easing.Quadratic.Out)
|
|
324
|
-
.onUpdate((data) => {
|
|
325
|
-
if (isNaN(data.scrollPosition)) {
|
|
326
|
-
return;
|
|
327
|
-
}
|
|
328
|
-
this.renderer.setProperty(scrollElement, this._scrollType, data.scrollPosition);
|
|
329
|
-
this.refresh_internal(false);
|
|
330
|
-
})
|
|
331
|
-
.onStop(() => {
|
|
332
|
-
cancelAnimationFrame(animationRequest);
|
|
333
|
-
})
|
|
334
|
-
.start();
|
|
335
|
-
const animate = (time) => {
|
|
336
|
-
if (!newTween["isPlaying"]()) {
|
|
337
|
-
return;
|
|
338
|
-
}
|
|
339
|
-
newTween.update(time);
|
|
340
|
-
if (tweenConfigObj.scrollPosition === scrollPosition) {
|
|
341
|
-
this.refresh_internal(false, animationCompletedCallback);
|
|
342
|
-
return;
|
|
343
|
-
}
|
|
344
|
-
this.zone.runOutsideAngular(() => {
|
|
345
|
-
animationRequest = requestAnimationFrame(animate);
|
|
346
|
-
});
|
|
347
|
-
};
|
|
348
|
-
animate();
|
|
349
|
-
this.currentTween = newTween;
|
|
350
|
-
}
|
|
351
|
-
getElementSize(element) {
|
|
352
|
-
const result = element.getBoundingClientRect();
|
|
353
|
-
const styles = getComputedStyle(element);
|
|
354
|
-
const marginTop = parseInt(styles['margin-top'], 10) || 0;
|
|
355
|
-
const marginBottom = parseInt(styles['margin-bottom'], 10) || 0;
|
|
356
|
-
const marginLeft = parseInt(styles['margin-left'], 10) || 0;
|
|
357
|
-
const marginRight = parseInt(styles['margin-right'], 10) || 0;
|
|
358
|
-
return {
|
|
359
|
-
top: result.top + marginTop,
|
|
360
|
-
bottom: result.bottom + marginBottom,
|
|
361
|
-
left: result.left + marginLeft,
|
|
362
|
-
right: result.right + marginRight,
|
|
363
|
-
width: result.width + marginLeft + marginRight,
|
|
364
|
-
height: result.height + marginTop + marginBottom
|
|
365
|
-
};
|
|
366
|
-
}
|
|
367
|
-
getContent() {
|
|
368
|
-
const content = (this.containerElementRef && this.containerElementRef.nativeElement) || this.contentElementRef.nativeElement;
|
|
369
|
-
return content;
|
|
370
|
-
}
|
|
371
|
-
checkScrollElementResized() {
|
|
372
|
-
const boundingRect = this.getElementSize(this.getScrollElement());
|
|
373
|
-
let sizeChanged;
|
|
374
|
-
if (!this.previousScrollBoundingRect) {
|
|
375
|
-
sizeChanged = true;
|
|
376
|
-
}
|
|
377
|
-
else {
|
|
378
|
-
const widthChange = Math.abs(boundingRect.width - this.previousScrollBoundingRect.width);
|
|
379
|
-
const heightChange = Math.abs(boundingRect.height - this.previousScrollBoundingRect.height);
|
|
380
|
-
sizeChanged = widthChange > this.resizeBypassRefreshThreshold || heightChange > this.resizeBypassRefreshThreshold;
|
|
381
|
-
}
|
|
382
|
-
if (sizeChanged) {
|
|
383
|
-
this.previousScrollBoundingRect = boundingRect;
|
|
384
|
-
if (boundingRect.width > 0 && boundingRect.height > 0) {
|
|
385
|
-
this.refresh_internal(false);
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
updateDirection() {
|
|
390
|
-
if (this.horizontal) {
|
|
391
|
-
this._childScrollDim = 'childWidth';
|
|
392
|
-
this._invisiblePaddingProperty = 'scaleX';
|
|
393
|
-
this._marginDir = 'margin-left';
|
|
394
|
-
this._offsetType = 'offsetLeft';
|
|
395
|
-
this._pageOffsetType = 'pageXOffset';
|
|
396
|
-
this._scrollType = 'scrollLeft';
|
|
397
|
-
this._translateDir = 'translateX';
|
|
398
|
-
}
|
|
399
|
-
else {
|
|
400
|
-
this._childScrollDim = 'childHeight';
|
|
401
|
-
this._invisiblePaddingProperty = 'scaleY';
|
|
402
|
-
this._marginDir = 'margin-top';
|
|
403
|
-
this._offsetType = 'offsetTop';
|
|
404
|
-
this._pageOffsetType = 'pageYOffset';
|
|
405
|
-
this._scrollType = 'scrollTop';
|
|
406
|
-
this._translateDir = 'translateY';
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
debounce(func, wait, ...args) {
|
|
410
|
-
const throttled = this.throttleTrailing(func, wait);
|
|
411
|
-
const result = function () {
|
|
412
|
-
throttled['cancel']();
|
|
413
|
-
throttled.apply(this, args);
|
|
414
|
-
};
|
|
415
|
-
result['cancel'] = function () {
|
|
416
|
-
throttled['cancel']();
|
|
417
|
-
};
|
|
418
|
-
return result;
|
|
419
|
-
}
|
|
420
|
-
throttleTrailing(func, wait, ...args) {
|
|
421
|
-
let timeout = undefined;
|
|
422
|
-
let _arguments = args;
|
|
423
|
-
const result = function () {
|
|
424
|
-
const _this = this;
|
|
425
|
-
_arguments = args;
|
|
426
|
-
if (timeout) {
|
|
427
|
-
return;
|
|
428
|
-
}
|
|
429
|
-
if (wait <= 0) {
|
|
430
|
-
func.apply(_this, _arguments);
|
|
431
|
-
}
|
|
432
|
-
else {
|
|
433
|
-
timeout = setTimeout(function () {
|
|
434
|
-
timeout = undefined;
|
|
435
|
-
func.apply(_this, _arguments);
|
|
436
|
-
}, wait);
|
|
437
|
-
}
|
|
438
|
-
};
|
|
439
|
-
result['cancel'] = function () {
|
|
440
|
-
if (timeout) {
|
|
441
|
-
clearTimeout(timeout);
|
|
442
|
-
timeout = undefined;
|
|
443
|
-
}
|
|
444
|
-
};
|
|
445
|
-
return result;
|
|
446
|
-
}
|
|
447
|
-
refresh_internal(itemsArrayModified, refreshCompletedCallback = undefined, maxRunTimes = 2) {
|
|
448
|
-
//note: maxRunTimes is to force it to keep recalculating if the previous iteration caused a re-render (different sliced items in viewport or scrollPosition changed).
|
|
449
|
-
//The default of 2x max will probably be accurate enough without causing too large a performance bottleneck
|
|
450
|
-
//The code would typically quit out on the 2nd iteration anyways. The main time it'd think more than 2 runs would be necessary would be for vastly different sized child items or if this is the 1st time the items array was initialized.
|
|
451
|
-
//Without maxRunTimes, If the user is actively scrolling this code would become an infinite loop until they stopped scrolling. This would be okay, except each scroll event would start an additional infinte loop. We want to short-circuit it to prevent this.
|
|
452
|
-
if (itemsArrayModified && this.previousViewPort && this.previousViewPort.scrollStartPosition > 0) {
|
|
453
|
-
//if items were prepended, scroll forward to keep same items visible
|
|
454
|
-
const oldViewPort = this.previousViewPort;
|
|
455
|
-
const oldViewPortItems = this.viewPortItems;
|
|
456
|
-
const oldRefreshCompletedCallback = refreshCompletedCallback;
|
|
457
|
-
refreshCompletedCallback = () => {
|
|
458
|
-
const scrollLengthDelta = this.previousViewPort.scrollLength - oldViewPort.scrollLength;
|
|
459
|
-
if (scrollLengthDelta > 0 && this.viewPortItems) {
|
|
460
|
-
const oldStartItem = oldViewPortItems[0];
|
|
461
|
-
const oldStartItemIndex = this.items.findIndex(x => this.compareItems(oldStartItem, x));
|
|
462
|
-
if (oldStartItemIndex > this.previousViewPort.startIndexWithBuffer) {
|
|
463
|
-
let itemOrderChanged = false;
|
|
464
|
-
for (let i = 1; i < this.viewPortItems.length; ++i) {
|
|
465
|
-
if (!this.compareItems(this.items[oldStartItemIndex + i], oldViewPortItems[i])) {
|
|
466
|
-
itemOrderChanged = true;
|
|
467
|
-
break;
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
if (!itemOrderChanged) {
|
|
471
|
-
this.scrollToPosition(this.previousViewPort.scrollStartPosition + scrollLengthDelta, 0, oldRefreshCompletedCallback);
|
|
472
|
-
return;
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
if (oldRefreshCompletedCallback) {
|
|
477
|
-
oldRefreshCompletedCallback();
|
|
478
|
-
}
|
|
479
|
-
};
|
|
480
|
-
}
|
|
481
|
-
this.zone.runOutsideAngular(() => {
|
|
482
|
-
requestAnimationFrame(() => {
|
|
483
|
-
if (itemsArrayModified) {
|
|
484
|
-
this.resetWrapGroupDimensions();
|
|
485
|
-
}
|
|
486
|
-
const viewport = this.calculateViewport();
|
|
487
|
-
const startChanged = itemsArrayModified || viewport.startIndex !== this.previousViewPort.startIndex;
|
|
488
|
-
const endChanged = itemsArrayModified || viewport.endIndex !== this.previousViewPort.endIndex;
|
|
489
|
-
const scrollLengthChanged = viewport.scrollLength !== this.previousViewPort.scrollLength;
|
|
490
|
-
const paddingChanged = viewport.padding !== this.previousViewPort.padding;
|
|
491
|
-
const scrollPositionChanged = viewport.scrollStartPosition !== this.previousViewPort.scrollStartPosition || viewport.scrollEndPosition !== this.previousViewPort.scrollEndPosition || viewport.maxScrollPosition !== this.previousViewPort.maxScrollPosition;
|
|
492
|
-
const scrollDirection = this.previousViewPort.endIndex <= viewport.endIndex ? 'forward' : 'backward';
|
|
493
|
-
this.previousViewPort = viewport;
|
|
494
|
-
if (scrollLengthChanged) {
|
|
495
|
-
this.renderer.setStyle(this.invisiblePaddingElementRef.nativeElement, 'transform', `${this._invisiblePaddingProperty}(${viewport.scrollLength})`);
|
|
496
|
-
this.renderer.setStyle(this.invisiblePaddingElementRef.nativeElement, 'webkitTransform', `${this._invisiblePaddingProperty}(${viewport.scrollLength})`);
|
|
497
|
-
}
|
|
498
|
-
if (paddingChanged) {
|
|
499
|
-
if (this.useMarginInsteadOfTranslate) {
|
|
500
|
-
this.renderer.setStyle(this.contentElementRef.nativeElement, this._marginDir, `${viewport.padding}px`);
|
|
501
|
-
}
|
|
502
|
-
else {
|
|
503
|
-
this.renderer.setStyle(this.contentElementRef.nativeElement, 'transform', `${this._translateDir}(${viewport.padding}px)`);
|
|
504
|
-
this.renderer.setStyle(this.contentElementRef.nativeElement, 'webkitTransform', `${this._translateDir}(${viewport.padding}px)`);
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
if (this.headerElementRef) {
|
|
508
|
-
const scrollPosition = this.getScrollElement()[this._scrollType];
|
|
509
|
-
const containerOffset = this.getElementsOffset();
|
|
510
|
-
const offset = Math.max(scrollPosition - viewport.padding - containerOffset + this.headerElementRef.nativeElement.clientHeight, 0);
|
|
511
|
-
this.renderer.setStyle(this.headerElementRef.nativeElement, 'transform', `${this._translateDir}(${offset}px)`);
|
|
512
|
-
this.renderer.setStyle(this.headerElementRef.nativeElement, 'webkitTransform', `${this._translateDir}(${offset}px)`);
|
|
513
|
-
}
|
|
514
|
-
const changeEventArg = (startChanged || endChanged) ? {
|
|
515
|
-
startIndex: viewport.startIndex,
|
|
516
|
-
endIndex: viewport.endIndex,
|
|
517
|
-
scrollStartPosition: viewport.scrollStartPosition,
|
|
518
|
-
scrollEndPosition: viewport.scrollEndPosition,
|
|
519
|
-
scrollDirection: scrollDirection,
|
|
520
|
-
startIndexWithBuffer: viewport.startIndexWithBuffer,
|
|
521
|
-
endIndexWithBuffer: viewport.endIndexWithBuffer,
|
|
522
|
-
maxScrollPosition: viewport.maxScrollPosition,
|
|
523
|
-
} : undefined;
|
|
524
|
-
if (startChanged || endChanged || scrollPositionChanged) {
|
|
525
|
-
const handleChanged = () => {
|
|
526
|
-
// update the scroll list to trigger re-render of components in viewport
|
|
527
|
-
this.viewPortItems = viewport.startIndexWithBuffer >= 0 && viewport.endIndexWithBuffer >= 0 ? this.items.slice(viewport.startIndexWithBuffer, viewport.endIndexWithBuffer + 1) : [];
|
|
528
|
-
this.vsUpdate.emit(this.viewPortItems);
|
|
529
|
-
if (startChanged) {
|
|
530
|
-
this.vsStart.emit(changeEventArg);
|
|
531
|
-
}
|
|
532
|
-
if (endChanged) {
|
|
533
|
-
this.vsEnd.emit(changeEventArg);
|
|
534
|
-
}
|
|
535
|
-
if (startChanged || endChanged) {
|
|
536
|
-
this.changeDetectorRef.markForCheck();
|
|
537
|
-
this.vsChange.emit(changeEventArg);
|
|
538
|
-
}
|
|
539
|
-
if (maxRunTimes > 0) {
|
|
540
|
-
this.refresh_internal(false, refreshCompletedCallback, maxRunTimes - 1);
|
|
541
|
-
return;
|
|
542
|
-
}
|
|
543
|
-
if (refreshCompletedCallback) {
|
|
544
|
-
refreshCompletedCallback();
|
|
545
|
-
}
|
|
546
|
-
};
|
|
547
|
-
if (this.executeRefreshOutsideAngularZone) {
|
|
548
|
-
handleChanged();
|
|
549
|
-
}
|
|
550
|
-
else {
|
|
551
|
-
this.zone.run(handleChanged);
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
else {
|
|
555
|
-
if (maxRunTimes > 0 && (scrollLengthChanged || paddingChanged)) {
|
|
556
|
-
this.refresh_internal(false, refreshCompletedCallback, maxRunTimes - 1);
|
|
557
|
-
return;
|
|
558
|
-
}
|
|
559
|
-
if (refreshCompletedCallback) {
|
|
560
|
-
refreshCompletedCallback();
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
});
|
|
564
|
-
});
|
|
565
|
-
}
|
|
566
|
-
getScrollElement() {
|
|
567
|
-
return this.parentScroll instanceof Window ? document.scrollingElement || document.documentElement || document.body : this.parentScroll || this.element.nativeElement;
|
|
568
|
-
}
|
|
569
|
-
addScrollEventHandlers() {
|
|
570
|
-
if (this.isAngularUniversalSSR) {
|
|
571
|
-
return;
|
|
572
|
-
}
|
|
573
|
-
const scrollElement = this.getScrollElement();
|
|
574
|
-
this.removeScrollEventHandlers();
|
|
575
|
-
this.zone.runOutsideAngular(() => {
|
|
576
|
-
if (this.parentScroll instanceof Window) {
|
|
577
|
-
this.disposeScrollHandler = this.renderer.listen('window', 'scroll', this.onScroll);
|
|
578
|
-
this.disposeResizeHandler = this.renderer.listen('window', 'resize', this.onScroll);
|
|
579
|
-
}
|
|
580
|
-
else {
|
|
581
|
-
this.disposeScrollHandler = this.renderer.listen(scrollElement, 'scroll', this.onScroll);
|
|
582
|
-
if (this._checkResizeInterval > 0) {
|
|
583
|
-
this.checkScrollElementResizedTimer = setInterval(() => { this.checkScrollElementResized(); }, this._checkResizeInterval);
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
});
|
|
587
|
-
}
|
|
588
|
-
removeScrollEventHandlers() {
|
|
589
|
-
if (this.checkScrollElementResizedTimer) {
|
|
590
|
-
clearInterval(this.checkScrollElementResizedTimer);
|
|
591
|
-
}
|
|
592
|
-
if (this.disposeScrollHandler) {
|
|
593
|
-
this.disposeScrollHandler();
|
|
594
|
-
this.disposeScrollHandler = undefined;
|
|
595
|
-
}
|
|
596
|
-
if (this.disposeResizeHandler) {
|
|
597
|
-
this.disposeResizeHandler();
|
|
598
|
-
this.disposeResizeHandler = undefined;
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
getElementsOffset() {
|
|
602
|
-
if (this.isAngularUniversalSSR) {
|
|
603
|
-
return 0;
|
|
604
|
-
}
|
|
605
|
-
let offset = 0;
|
|
606
|
-
if (this.containerElementRef && this.containerElementRef.nativeElement) {
|
|
607
|
-
offset += this.containerElementRef.nativeElement[this._offsetType];
|
|
608
|
-
}
|
|
609
|
-
if (this.parentScroll) {
|
|
610
|
-
const scrollElement = this.getScrollElement();
|
|
611
|
-
const elementClientRect = this.getElementSize(this.element.nativeElement);
|
|
612
|
-
const scrollClientRect = this.getElementSize(scrollElement);
|
|
613
|
-
if (this.horizontal) {
|
|
614
|
-
offset += elementClientRect.left - scrollClientRect.left;
|
|
615
|
-
}
|
|
616
|
-
else {
|
|
617
|
-
offset += elementClientRect.top - scrollClientRect.top;
|
|
618
|
-
}
|
|
619
|
-
if (!(this.parentScroll instanceof Window)) {
|
|
620
|
-
offset += scrollElement[this._scrollType];
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
return offset;
|
|
624
|
-
}
|
|
625
|
-
countItemsPerWrapGroup() {
|
|
626
|
-
if (this.isAngularUniversalSSR) {
|
|
627
|
-
return Math.round(this.horizontal ? this.ssrViewportHeight / this.ssrChildHeight : this.ssrViewportWidth / this.ssrChildWidth);
|
|
628
|
-
}
|
|
629
|
-
const propertyName = this.horizontal ? 'offsetLeft' : 'offsetTop';
|
|
630
|
-
const children = this.getContent().children;
|
|
631
|
-
const childrenLength = children ? children.length : 0;
|
|
632
|
-
if (childrenLength === 0) {
|
|
633
|
-
return 1;
|
|
634
|
-
}
|
|
635
|
-
const firstOffset = children[0][propertyName];
|
|
636
|
-
let result = 1;
|
|
637
|
-
while (result < childrenLength && firstOffset === children[result][propertyName]) {
|
|
638
|
-
++result;
|
|
639
|
-
}
|
|
640
|
-
return result;
|
|
641
|
-
}
|
|
642
|
-
getScrollStartPosition() {
|
|
643
|
-
let windowScrollValue = undefined;
|
|
644
|
-
if (this.parentScroll instanceof Window) {
|
|
645
|
-
windowScrollValue = window[this._pageOffsetType];
|
|
646
|
-
}
|
|
647
|
-
return windowScrollValue || this.getScrollElement()[this._scrollType] || 0;
|
|
648
|
-
}
|
|
649
|
-
resetWrapGroupDimensions() {
|
|
650
|
-
const oldWrapGroupDimensions = this.wrapGroupDimensions;
|
|
651
|
-
this.invalidateAllCachedMeasurements();
|
|
652
|
-
if (!this.enableUnequalChildrenSizes || !oldWrapGroupDimensions || oldWrapGroupDimensions.numberOfKnownWrapGroupChildSizes === 0) {
|
|
653
|
-
return;
|
|
654
|
-
}
|
|
655
|
-
const itemsPerWrapGroup = this.countItemsPerWrapGroup();
|
|
656
|
-
for (let wrapGroupIndex = 0; wrapGroupIndex < oldWrapGroupDimensions.maxChildSizePerWrapGroup.length; ++wrapGroupIndex) {
|
|
657
|
-
const oldWrapGroupDimension = oldWrapGroupDimensions.maxChildSizePerWrapGroup[wrapGroupIndex];
|
|
658
|
-
if (!oldWrapGroupDimension || !oldWrapGroupDimension.items || !oldWrapGroupDimension.items.length) {
|
|
659
|
-
continue;
|
|
660
|
-
}
|
|
661
|
-
if (oldWrapGroupDimension.items.length !== itemsPerWrapGroup) {
|
|
662
|
-
return;
|
|
663
|
-
}
|
|
664
|
-
let itemsChanged = false;
|
|
665
|
-
const arrayStartIndex = itemsPerWrapGroup * wrapGroupIndex;
|
|
666
|
-
for (let i = 0; i < itemsPerWrapGroup; ++i) {
|
|
667
|
-
if (!this.compareItems(oldWrapGroupDimension.items[i], this.items[arrayStartIndex + i])) {
|
|
668
|
-
itemsChanged = true;
|
|
669
|
-
break;
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
if (!itemsChanged) {
|
|
673
|
-
++this.wrapGroupDimensions.numberOfKnownWrapGroupChildSizes;
|
|
674
|
-
this.wrapGroupDimensions.sumOfKnownWrapGroupChildWidths += oldWrapGroupDimension.childWidth || 0;
|
|
675
|
-
this.wrapGroupDimensions.sumOfKnownWrapGroupChildHeights += oldWrapGroupDimension.childHeight || 0;
|
|
676
|
-
this.wrapGroupDimensions.maxChildSizePerWrapGroup[wrapGroupIndex] = oldWrapGroupDimension;
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
calculateDimensions() {
|
|
681
|
-
const scrollElement = this.getScrollElement();
|
|
682
|
-
const maxCalculatedScrollBarSize = 25; // Note: Formula to auto-calculate doesn't work for ParentScroll, so we default to this if not set by consuming application
|
|
683
|
-
this.calculatedScrollbarHeight = Math.max(Math.min(scrollElement.offsetHeight - scrollElement.clientHeight, maxCalculatedScrollBarSize), this.calculatedScrollbarHeight);
|
|
684
|
-
this.calculatedScrollbarWidth = Math.max(Math.min(scrollElement.offsetWidth - scrollElement.clientWidth, maxCalculatedScrollBarSize), this.calculatedScrollbarWidth);
|
|
685
|
-
let viewportWidth = scrollElement.offsetWidth - (this.scrollbarWidth || this.calculatedScrollbarWidth || (this.horizontal ? 0 : maxCalculatedScrollBarSize));
|
|
686
|
-
let viewportHeight = scrollElement.offsetHeight - (this.scrollbarHeight || this.calculatedScrollbarHeight || (this.horizontal ? maxCalculatedScrollBarSize : 0));
|
|
687
|
-
const content = this.getContent();
|
|
688
|
-
const itemsPerWrapGroup = this.countItemsPerWrapGroup();
|
|
689
|
-
let wrapGroupsPerPage;
|
|
690
|
-
let defaultChildWidth;
|
|
691
|
-
let defaultChildHeight;
|
|
692
|
-
if (this.isAngularUniversalSSR) {
|
|
693
|
-
viewportWidth = this.ssrViewportWidth;
|
|
694
|
-
viewportHeight = this.ssrViewportHeight;
|
|
695
|
-
defaultChildWidth = this.ssrChildWidth;
|
|
696
|
-
defaultChildHeight = this.ssrChildHeight;
|
|
697
|
-
const itemsPerRow = Math.max(Math.ceil(viewportWidth / defaultChildWidth), 1);
|
|
698
|
-
const itemsPerCol = Math.max(Math.ceil(viewportHeight / defaultChildHeight), 1);
|
|
699
|
-
wrapGroupsPerPage = this.horizontal ? itemsPerRow : itemsPerCol;
|
|
700
|
-
}
|
|
701
|
-
else if (!this.enableUnequalChildrenSizes) {
|
|
702
|
-
if (content.children.length > 0) {
|
|
703
|
-
if (!this.childWidth || !this.childHeight) {
|
|
704
|
-
if (!this.minMeasuredChildWidth && viewportWidth > 0) {
|
|
705
|
-
this.minMeasuredChildWidth = viewportWidth;
|
|
706
|
-
}
|
|
707
|
-
if (!this.minMeasuredChildHeight && viewportHeight > 0) {
|
|
708
|
-
this.minMeasuredChildHeight = viewportHeight;
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
const child = content.children[0];
|
|
712
|
-
const clientRect = this.getElementSize(child);
|
|
713
|
-
this.minMeasuredChildWidth = Math.min(this.minMeasuredChildWidth, clientRect.width);
|
|
714
|
-
this.minMeasuredChildHeight = Math.min(this.minMeasuredChildHeight, clientRect.height);
|
|
715
|
-
// Added for getting the child height (for card view, return all the clientRect object).
|
|
716
|
-
// if (this._lastChildRect === null ||
|
|
717
|
-
// (clientRect?.height !== 0 && (
|
|
718
|
-
// Math.round(this._lastChildRect?.height) !== Math.round(clientRect?.height) ||
|
|
719
|
-
// Math.round(this._lastChildRect?.width) !== Math.round(clientRect?.width))
|
|
720
|
-
// )) {
|
|
721
|
-
// this._lastChildRect = clientRect;
|
|
722
|
-
// this.vsChildRectChange.emit(clientRect);
|
|
723
|
-
// }
|
|
724
|
-
}
|
|
725
|
-
defaultChildWidth = this.childWidth || this.minMeasuredChildWidth || viewportWidth;
|
|
726
|
-
defaultChildHeight = this.childHeight || this.minMeasuredChildHeight || viewportHeight;
|
|
727
|
-
const itemsPerRow = Math.max(Math.ceil(viewportWidth / defaultChildWidth), 1);
|
|
728
|
-
const itemsPerCol = Math.max(Math.ceil(viewportHeight / defaultChildHeight), 1);
|
|
729
|
-
wrapGroupsPerPage = this.horizontal ? itemsPerRow : itemsPerCol;
|
|
730
|
-
}
|
|
731
|
-
else {
|
|
732
|
-
let scrollOffset = scrollElement[this._scrollType] - (this.previousViewPort ? this.previousViewPort.padding : 0);
|
|
733
|
-
let arrayStartIndex = this.previousViewPort.startIndexWithBuffer || 0;
|
|
734
|
-
let wrapGroupIndex = Math.ceil(arrayStartIndex / itemsPerWrapGroup);
|
|
735
|
-
let maxWidthForWrapGroup = 0;
|
|
736
|
-
let maxHeightForWrapGroup = 0;
|
|
737
|
-
let sumOfVisibleMaxWidths = 0;
|
|
738
|
-
let sumOfVisibleMaxHeights = 0;
|
|
739
|
-
wrapGroupsPerPage = 0;
|
|
740
|
-
for (let i = 0; i < content.children.length; ++i) {
|
|
741
|
-
++arrayStartIndex;
|
|
742
|
-
const child = content.children[i];
|
|
743
|
-
const clientRect = this.getElementSize(child);
|
|
744
|
-
maxWidthForWrapGroup = Math.max(maxWidthForWrapGroup, clientRect.width);
|
|
745
|
-
maxHeightForWrapGroup = Math.max(maxHeightForWrapGroup, clientRect.height);
|
|
746
|
-
if (arrayStartIndex % itemsPerWrapGroup === 0) {
|
|
747
|
-
const oldValue = this.wrapGroupDimensions.maxChildSizePerWrapGroup[wrapGroupIndex];
|
|
748
|
-
if (oldValue) {
|
|
749
|
-
--this.wrapGroupDimensions.numberOfKnownWrapGroupChildSizes;
|
|
750
|
-
this.wrapGroupDimensions.sumOfKnownWrapGroupChildWidths -= oldValue.childWidth || 0;
|
|
751
|
-
this.wrapGroupDimensions.sumOfKnownWrapGroupChildHeights -= oldValue.childHeight || 0;
|
|
752
|
-
}
|
|
753
|
-
++this.wrapGroupDimensions.numberOfKnownWrapGroupChildSizes;
|
|
754
|
-
const items = this.items.slice(arrayStartIndex - itemsPerWrapGroup, arrayStartIndex);
|
|
755
|
-
this.wrapGroupDimensions.maxChildSizePerWrapGroup[wrapGroupIndex] = {
|
|
756
|
-
childWidth: maxWidthForWrapGroup,
|
|
757
|
-
childHeight: maxHeightForWrapGroup,
|
|
758
|
-
items: items
|
|
759
|
-
};
|
|
760
|
-
this.wrapGroupDimensions.sumOfKnownWrapGroupChildWidths += maxWidthForWrapGroup;
|
|
761
|
-
this.wrapGroupDimensions.sumOfKnownWrapGroupChildHeights += maxHeightForWrapGroup;
|
|
762
|
-
if (this.horizontal) {
|
|
763
|
-
let maxVisibleWidthForWrapGroup = Math.min(maxWidthForWrapGroup, Math.max(viewportWidth - sumOfVisibleMaxWidths, 0));
|
|
764
|
-
if (scrollOffset > 0) {
|
|
765
|
-
const scrollOffsetToRemove = Math.min(scrollOffset, maxVisibleWidthForWrapGroup);
|
|
766
|
-
maxVisibleWidthForWrapGroup -= scrollOffsetToRemove;
|
|
767
|
-
scrollOffset -= scrollOffsetToRemove;
|
|
768
|
-
}
|
|
769
|
-
sumOfVisibleMaxWidths += maxVisibleWidthForWrapGroup;
|
|
770
|
-
if (maxVisibleWidthForWrapGroup > 0 && viewportWidth >= sumOfVisibleMaxWidths) {
|
|
771
|
-
++wrapGroupsPerPage;
|
|
772
|
-
}
|
|
773
|
-
}
|
|
774
|
-
else {
|
|
775
|
-
let maxVisibleHeightForWrapGroup = Math.min(maxHeightForWrapGroup, Math.max(viewportHeight - sumOfVisibleMaxHeights, 0));
|
|
776
|
-
if (scrollOffset > 0) {
|
|
777
|
-
const scrollOffsetToRemove = Math.min(scrollOffset, maxVisibleHeightForWrapGroup);
|
|
778
|
-
maxVisibleHeightForWrapGroup -= scrollOffsetToRemove;
|
|
779
|
-
scrollOffset -= scrollOffsetToRemove;
|
|
780
|
-
}
|
|
781
|
-
sumOfVisibleMaxHeights += maxVisibleHeightForWrapGroup;
|
|
782
|
-
if (maxVisibleHeightForWrapGroup > 0 && viewportHeight >= sumOfVisibleMaxHeights) {
|
|
783
|
-
++wrapGroupsPerPage;
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
++wrapGroupIndex;
|
|
787
|
-
maxWidthForWrapGroup = 0;
|
|
788
|
-
maxHeightForWrapGroup = 0;
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
const averageChildWidth = this.wrapGroupDimensions.sumOfKnownWrapGroupChildWidths / this.wrapGroupDimensions.numberOfKnownWrapGroupChildSizes;
|
|
792
|
-
const averageChildHeight = this.wrapGroupDimensions.sumOfKnownWrapGroupChildHeights / this.wrapGroupDimensions.numberOfKnownWrapGroupChildSizes;
|
|
793
|
-
defaultChildWidth = this.childWidth || averageChildWidth || viewportWidth;
|
|
794
|
-
defaultChildHeight = this.childHeight || averageChildHeight || viewportHeight;
|
|
795
|
-
if (this.horizontal) {
|
|
796
|
-
if (viewportWidth > sumOfVisibleMaxWidths) {
|
|
797
|
-
wrapGroupsPerPage += Math.ceil((viewportWidth - sumOfVisibleMaxWidths) / defaultChildWidth);
|
|
798
|
-
}
|
|
799
|
-
}
|
|
800
|
-
else {
|
|
801
|
-
if (viewportHeight > sumOfVisibleMaxHeights) {
|
|
802
|
-
wrapGroupsPerPage += Math.ceil((viewportHeight - sumOfVisibleMaxHeights) / defaultChildHeight);
|
|
803
|
-
}
|
|
804
|
-
}
|
|
805
|
-
}
|
|
806
|
-
const itemCount = this.items.length;
|
|
807
|
-
const itemsPerPage = itemsPerWrapGroup * wrapGroupsPerPage;
|
|
808
|
-
const pageCount_fractional = itemCount / itemsPerPage;
|
|
809
|
-
const numberOfWrapGroups = Math.ceil(itemCount / itemsPerWrapGroup);
|
|
810
|
-
let scrollLength = 0;
|
|
811
|
-
const defaultScrollLengthPerWrapGroup = this.horizontal ? defaultChildWidth : defaultChildHeight;
|
|
812
|
-
if (this.enableUnequalChildrenSizes) {
|
|
813
|
-
let numUnknownChildSizes = 0;
|
|
814
|
-
for (let i = 0; i < numberOfWrapGroups; ++i) {
|
|
815
|
-
const childSize = this.wrapGroupDimensions.maxChildSizePerWrapGroup[i] && this.wrapGroupDimensions.maxChildSizePerWrapGroup[i][this._childScrollDim];
|
|
816
|
-
if (childSize) {
|
|
817
|
-
scrollLength += childSize;
|
|
818
|
-
}
|
|
819
|
-
else {
|
|
820
|
-
++numUnknownChildSizes;
|
|
821
|
-
}
|
|
822
|
-
}
|
|
823
|
-
scrollLength += Math.round(numUnknownChildSizes * defaultScrollLengthPerWrapGroup);
|
|
824
|
-
}
|
|
825
|
-
else {
|
|
826
|
-
scrollLength = numberOfWrapGroups * defaultScrollLengthPerWrapGroup;
|
|
827
|
-
}
|
|
828
|
-
if (this.headerElementRef) {
|
|
829
|
-
scrollLength += this.headerElementRef.nativeElement.clientHeight;
|
|
830
|
-
}
|
|
831
|
-
const viewportLength = this.horizontal ? viewportWidth : viewportHeight;
|
|
832
|
-
const maxScrollPosition = Math.max(scrollLength - viewportLength, 0);
|
|
833
|
-
return {
|
|
834
|
-
childHeight: defaultChildHeight,
|
|
835
|
-
childWidth: defaultChildWidth,
|
|
836
|
-
itemCount: itemCount,
|
|
837
|
-
itemsPerPage: itemsPerPage,
|
|
838
|
-
itemsPerWrapGroup: itemsPerWrapGroup,
|
|
839
|
-
maxScrollPosition: maxScrollPosition,
|
|
840
|
-
pageCount_fractional: pageCount_fractional,
|
|
841
|
-
scrollLength: scrollLength,
|
|
842
|
-
viewportLength: viewportLength,
|
|
843
|
-
wrapGroupsPerPage: wrapGroupsPerPage,
|
|
844
|
-
};
|
|
845
|
-
}
|
|
846
|
-
calculatePadding(arrayStartIndexWithBuffer, dimensions) {
|
|
847
|
-
if (dimensions.itemCount === 0) {
|
|
848
|
-
return 0;
|
|
849
|
-
}
|
|
850
|
-
const defaultScrollLengthPerWrapGroup = dimensions[this._childScrollDim];
|
|
851
|
-
const startingWrapGroupIndex = Math.floor(arrayStartIndexWithBuffer / dimensions.itemsPerWrapGroup) || 0;
|
|
852
|
-
if (!this.enableUnequalChildrenSizes) {
|
|
853
|
-
return defaultScrollLengthPerWrapGroup * startingWrapGroupIndex;
|
|
854
|
-
}
|
|
855
|
-
let numUnknownChildSizes = 0;
|
|
856
|
-
let result = 0;
|
|
857
|
-
for (let i = 0; i < startingWrapGroupIndex; ++i) {
|
|
858
|
-
const childSize = this.wrapGroupDimensions.maxChildSizePerWrapGroup[i] && this.wrapGroupDimensions.maxChildSizePerWrapGroup[i][this._childScrollDim];
|
|
859
|
-
if (childSize) {
|
|
860
|
-
result += childSize;
|
|
861
|
-
}
|
|
862
|
-
else {
|
|
863
|
-
++numUnknownChildSizes;
|
|
864
|
-
}
|
|
865
|
-
}
|
|
866
|
-
result += Math.round(numUnknownChildSizes * defaultScrollLengthPerWrapGroup);
|
|
867
|
-
return result;
|
|
868
|
-
}
|
|
869
|
-
calculatePageInfo(scrollPosition, dimensions) {
|
|
870
|
-
let scrollPercentage = 0;
|
|
871
|
-
if (this.enableUnequalChildrenSizes) {
|
|
872
|
-
const numberOfWrapGroups = Math.ceil(dimensions.itemCount / dimensions.itemsPerWrapGroup);
|
|
873
|
-
let totalScrolledLength = 0;
|
|
874
|
-
const defaultScrollLengthPerWrapGroup = dimensions[this._childScrollDim];
|
|
875
|
-
for (let i = 0; i < numberOfWrapGroups; ++i) {
|
|
876
|
-
const childSize = this.wrapGroupDimensions.maxChildSizePerWrapGroup[i] && this.wrapGroupDimensions.maxChildSizePerWrapGroup[i][this._childScrollDim];
|
|
877
|
-
if (childSize) {
|
|
878
|
-
totalScrolledLength += childSize;
|
|
879
|
-
}
|
|
880
|
-
else {
|
|
881
|
-
totalScrolledLength += defaultScrollLengthPerWrapGroup;
|
|
882
|
-
}
|
|
883
|
-
if (scrollPosition < totalScrolledLength) {
|
|
884
|
-
scrollPercentage = i / numberOfWrapGroups;
|
|
885
|
-
break;
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
else {
|
|
890
|
-
scrollPercentage = scrollPosition / dimensions.scrollLength;
|
|
891
|
-
}
|
|
892
|
-
const startingArrayIndex_fractional = Math.min(Math.max(scrollPercentage * dimensions.pageCount_fractional, 0), dimensions.pageCount_fractional) * dimensions.itemsPerPage;
|
|
893
|
-
const maxStart = dimensions.itemCount - dimensions.itemsPerPage - 1;
|
|
894
|
-
let arrayStartIndex = Math.min(Math.floor(startingArrayIndex_fractional), maxStart);
|
|
895
|
-
arrayStartIndex -= arrayStartIndex % dimensions.itemsPerWrapGroup; // round down to start of wrapGroup
|
|
896
|
-
if (this.stripedTable) {
|
|
897
|
-
const bufferBoundary = 2 * dimensions.itemsPerWrapGroup;
|
|
898
|
-
if (arrayStartIndex % bufferBoundary !== 0) {
|
|
899
|
-
arrayStartIndex = Math.max(arrayStartIndex - arrayStartIndex % bufferBoundary, 0);
|
|
900
|
-
}
|
|
901
|
-
}
|
|
902
|
-
let arrayEndIndex = Math.ceil(startingArrayIndex_fractional) + dimensions.itemsPerPage - 1;
|
|
903
|
-
const endIndexWithinWrapGroup = (arrayEndIndex + 1) % dimensions.itemsPerWrapGroup;
|
|
904
|
-
if (endIndexWithinWrapGroup > 0) {
|
|
905
|
-
arrayEndIndex += dimensions.itemsPerWrapGroup - endIndexWithinWrapGroup; // round up to end of wrapGroup
|
|
906
|
-
}
|
|
907
|
-
if (isNaN(arrayStartIndex)) {
|
|
908
|
-
arrayStartIndex = 0;
|
|
909
|
-
}
|
|
910
|
-
if (isNaN(arrayEndIndex)) {
|
|
911
|
-
arrayEndIndex = 0;
|
|
912
|
-
}
|
|
913
|
-
arrayStartIndex = Math.min(Math.max(arrayStartIndex, 0), dimensions.itemCount - 1);
|
|
914
|
-
arrayEndIndex = Math.min(Math.max(arrayEndIndex, 0), dimensions.itemCount - 1);
|
|
915
|
-
const bufferSize = this.bufferAmount * dimensions.itemsPerWrapGroup;
|
|
916
|
-
const startIndexWithBuffer = Math.min(Math.max(arrayStartIndex - bufferSize, 0), dimensions.itemCount - 1);
|
|
917
|
-
const endIndexWithBuffer = Math.min(Math.max(arrayEndIndex + bufferSize, 0), dimensions.itemCount - 1);
|
|
918
|
-
return {
|
|
919
|
-
startIndex: arrayStartIndex,
|
|
920
|
-
endIndex: arrayEndIndex,
|
|
921
|
-
startIndexWithBuffer: startIndexWithBuffer,
|
|
922
|
-
endIndexWithBuffer: endIndexWithBuffer,
|
|
923
|
-
scrollStartPosition: scrollPosition,
|
|
924
|
-
scrollEndPosition: scrollPosition + dimensions.viewportLength,
|
|
925
|
-
maxScrollPosition: dimensions.maxScrollPosition
|
|
926
|
-
};
|
|
927
|
-
}
|
|
928
|
-
calculateViewport() {
|
|
929
|
-
const dimensions = this.calculateDimensions();
|
|
930
|
-
const offset = this.getElementsOffset();
|
|
931
|
-
let scrollStartPosition = this.getScrollStartPosition();
|
|
932
|
-
if (scrollStartPosition > (dimensions.scrollLength + offset) && !(this.parentScroll instanceof Window)) {
|
|
933
|
-
scrollStartPosition = dimensions.scrollLength;
|
|
934
|
-
}
|
|
935
|
-
else {
|
|
936
|
-
scrollStartPosition -= offset;
|
|
937
|
-
}
|
|
938
|
-
scrollStartPosition = Math.max(0, scrollStartPosition);
|
|
939
|
-
const pageInfo = this.calculatePageInfo(scrollStartPosition, dimensions);
|
|
940
|
-
const newPadding = this.calculatePadding(pageInfo.startIndexWithBuffer, dimensions);
|
|
941
|
-
const newScrollLength = dimensions.scrollLength;
|
|
942
|
-
return {
|
|
943
|
-
startIndex: pageInfo.startIndex,
|
|
944
|
-
endIndex: pageInfo.endIndex,
|
|
945
|
-
startIndexWithBuffer: pageInfo.startIndexWithBuffer,
|
|
946
|
-
endIndexWithBuffer: pageInfo.endIndexWithBuffer,
|
|
947
|
-
padding: Math.round(newPadding),
|
|
948
|
-
scrollLength: Math.round(newScrollLength),
|
|
949
|
-
scrollStartPosition: pageInfo.scrollStartPosition,
|
|
950
|
-
scrollEndPosition: pageInfo.scrollEndPosition,
|
|
951
|
-
maxScrollPosition: pageInfo.maxScrollPosition
|
|
952
|
-
};
|
|
953
|
-
}
|
|
954
|
-
}
|
|
955
|
-
VirtualScrollerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: VirtualScrollerComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: PLATFORM_ID }, { token: 'virtual-scroller-default-options', optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
1
|
+
import { Component, ContentChild, ElementRef, EventEmitter, Inject, Input, NgModule, Optional, Output, ViewChild, } from '@angular/core';
|
|
2
|
+
import { PLATFORM_ID } from '@angular/core';
|
|
3
|
+
import { isPlatformServer } from '@angular/common';
|
|
4
|
+
import { CommonModule } from '@angular/common';
|
|
5
|
+
import * as tween from '@tweenjs/tween.js';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
export function VIRTUAL_SCROLLER_DEFAULT_OPTIONS_FACTORY() {
|
|
8
|
+
return {
|
|
9
|
+
checkResizeInterval: 1000,
|
|
10
|
+
modifyOverflowStyleOfParentScroll: true,
|
|
11
|
+
resizeBypassRefreshThreshold: 5,
|
|
12
|
+
scrollAnimationTime: 750,
|
|
13
|
+
scrollDebounceTime: 0,
|
|
14
|
+
scrollThrottlingTime: 0,
|
|
15
|
+
stripedTable: false
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export class VirtualScrollerComponent {
|
|
19
|
+
constructor(element, renderer, zone, changeDetectorRef, platformId, options) {
|
|
20
|
+
this.element = element;
|
|
21
|
+
this.renderer = renderer;
|
|
22
|
+
this.zone = zone;
|
|
23
|
+
this.changeDetectorRef = changeDetectorRef;
|
|
24
|
+
this.window = window;
|
|
25
|
+
this._disable = false;
|
|
26
|
+
this.executeRefreshOutsideAngularZone = false;
|
|
27
|
+
this._enableUnequalChildrenSizes = false;
|
|
28
|
+
this.RTL = false;
|
|
29
|
+
this.useMarginInsteadOfTranslate = false;
|
|
30
|
+
this.ssrViewportWidth = 1920;
|
|
31
|
+
this.ssrViewportHeight = 1080;
|
|
32
|
+
this._items = [];
|
|
33
|
+
this.compareItems = (item1, item2) => item1 === item2;
|
|
34
|
+
// private _lastChildRect: DOMRect = null;
|
|
35
|
+
this.vsChildRectChange = new EventEmitter();
|
|
36
|
+
this.vsUpdate = new EventEmitter();
|
|
37
|
+
this.vsChange = new EventEmitter();
|
|
38
|
+
this.vsStart = new EventEmitter();
|
|
39
|
+
this.vsEnd = new EventEmitter();
|
|
40
|
+
this.calculatedScrollbarWidth = 0;
|
|
41
|
+
this.calculatedScrollbarHeight = 0;
|
|
42
|
+
this.padding = 0;
|
|
43
|
+
this.previousViewPort = {};
|
|
44
|
+
this.cachedPageSize = 0;
|
|
45
|
+
this.previousScrollNumberElements = 0;
|
|
46
|
+
this.isAngularUniversalSSR = isPlatformServer(platformId);
|
|
47
|
+
const defaultOptions = VIRTUAL_SCROLLER_DEFAULT_OPTIONS_FACTORY();
|
|
48
|
+
this.checkResizeInterval = options?.checkResizeInterval || defaultOptions.checkResizeInterval;
|
|
49
|
+
this.modifyOverflowStyleOfParentScroll = options?.modifyOverflowStyleOfParentScroll || defaultOptions.modifyOverflowStyleOfParentScroll;
|
|
50
|
+
this.resizeBypassRefreshThreshold = options?.resizeBypassRefreshThreshold || defaultOptions.resizeBypassRefreshThreshold;
|
|
51
|
+
this.scrollAnimationTime = options?.scrollAnimationTime || defaultOptions.scrollAnimationTime;
|
|
52
|
+
this.scrollDebounceTime = options?.scrollDebounceTime || defaultOptions.scrollDebounceTime;
|
|
53
|
+
this.scrollThrottlingTime = options?.scrollThrottlingTime || defaultOptions.scrollThrottlingTime;
|
|
54
|
+
this.scrollbarHeight = options?.scrollbarHeight || defaultOptions.scrollbarHeight;
|
|
55
|
+
this.scrollbarWidth = options?.scrollbarWidth || defaultOptions.scrollbarWidth;
|
|
56
|
+
this.stripedTable = options?.stripedTable || defaultOptions.stripedTable;
|
|
57
|
+
this.horizontal = false;
|
|
58
|
+
this.resetWrapGroupDimensions();
|
|
59
|
+
}
|
|
60
|
+
get viewPortInfo() {
|
|
61
|
+
const pageInfo = this.previousViewPort || {};
|
|
62
|
+
return {
|
|
63
|
+
startIndex: pageInfo.startIndex || 0,
|
|
64
|
+
endIndex: pageInfo.endIndex || 0,
|
|
65
|
+
scrollStartPosition: pageInfo.scrollStartPosition || 0,
|
|
66
|
+
scrollEndPosition: pageInfo.scrollEndPosition || 0,
|
|
67
|
+
scrollDirection: pageInfo.scrollDirection || 'forward',
|
|
68
|
+
maxScrollPosition: pageInfo.maxScrollPosition || 0,
|
|
69
|
+
startIndexWithBuffer: pageInfo.startIndexWithBuffer || 0,
|
|
70
|
+
endIndexWithBuffer: pageInfo.endIndexWithBuffer || 0,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
get disable() {
|
|
74
|
+
return this._disable;
|
|
75
|
+
}
|
|
76
|
+
set disable(value) {
|
|
77
|
+
if (this._disable === value) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
this._disable = value;
|
|
81
|
+
if (this._disable) {
|
|
82
|
+
this.removeScrollEventHandlers();
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
this.addScrollEventHandlers();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
get enableUnequalChildrenSizes() {
|
|
89
|
+
return this._enableUnequalChildrenSizes;
|
|
90
|
+
}
|
|
91
|
+
set enableUnequalChildrenSizes(value) {
|
|
92
|
+
if (this._enableUnequalChildrenSizes === value) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
this._enableUnequalChildrenSizes = value;
|
|
96
|
+
this.minMeasuredChildWidth = undefined;
|
|
97
|
+
this.minMeasuredChildHeight = undefined;
|
|
98
|
+
}
|
|
99
|
+
get bufferAmount() {
|
|
100
|
+
if (typeof (this._bufferAmount) === 'number' && this._bufferAmount > 0) {
|
|
101
|
+
return this._bufferAmount;
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
return this.enableUnequalChildrenSizes ? 5 : 0;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
set bufferAmount(value) {
|
|
108
|
+
this._bufferAmount = value;
|
|
109
|
+
}
|
|
110
|
+
get scrollThrottlingTime() {
|
|
111
|
+
return this._scrollThrottlingTime;
|
|
112
|
+
}
|
|
113
|
+
set scrollThrottlingTime(value) {
|
|
114
|
+
this._scrollThrottlingTime = value;
|
|
115
|
+
this.updateOnScrollFunction();
|
|
116
|
+
}
|
|
117
|
+
get scrollDebounceTime() {
|
|
118
|
+
return this._scrollDebounceTime;
|
|
119
|
+
}
|
|
120
|
+
set scrollDebounceTime(value) {
|
|
121
|
+
this._scrollDebounceTime = value;
|
|
122
|
+
this.updateOnScrollFunction();
|
|
123
|
+
}
|
|
124
|
+
updateOnScrollFunction() {
|
|
125
|
+
if (this.scrollDebounceTime) {
|
|
126
|
+
this.onScroll = this.debounce(() => {
|
|
127
|
+
this.refresh_internal(false);
|
|
128
|
+
}, this.scrollDebounceTime);
|
|
129
|
+
}
|
|
130
|
+
else if (this.scrollThrottlingTime) {
|
|
131
|
+
this.onScroll = this.throttleTrailing(() => {
|
|
132
|
+
this.refresh_internal(false);
|
|
133
|
+
}, this.scrollThrottlingTime);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
this.onScroll = () => {
|
|
137
|
+
this.refresh_internal(false);
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
get checkResizeInterval() {
|
|
142
|
+
return this._checkResizeInterval;
|
|
143
|
+
}
|
|
144
|
+
set checkResizeInterval(value) {
|
|
145
|
+
if (this._checkResizeInterval === value) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
this._checkResizeInterval = value;
|
|
149
|
+
this.addScrollEventHandlers();
|
|
150
|
+
}
|
|
151
|
+
get items() {
|
|
152
|
+
return this._items;
|
|
153
|
+
}
|
|
154
|
+
set items(value) {
|
|
155
|
+
if (value === this._items) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
this._items = value || [];
|
|
159
|
+
this.refresh_internal(true);
|
|
160
|
+
}
|
|
161
|
+
get horizontal() {
|
|
162
|
+
return this._horizontal;
|
|
163
|
+
}
|
|
164
|
+
set horizontal(value) {
|
|
165
|
+
this._horizontal = value;
|
|
166
|
+
this.updateDirection();
|
|
167
|
+
}
|
|
168
|
+
revertParentOverscroll() {
|
|
169
|
+
const scrollElement = this.getScrollElement();
|
|
170
|
+
if (scrollElement && this.oldParentScrollOverflow) {
|
|
171
|
+
scrollElement.style['overflow-y'] = this.oldParentScrollOverflow.y;
|
|
172
|
+
scrollElement.style['overflow-x'] = this.oldParentScrollOverflow.x;
|
|
173
|
+
}
|
|
174
|
+
this.oldParentScrollOverflow = undefined;
|
|
175
|
+
}
|
|
176
|
+
get parentScroll() {
|
|
177
|
+
return this._parentScroll;
|
|
178
|
+
}
|
|
179
|
+
set parentScroll(value) {
|
|
180
|
+
if (this._parentScroll === value) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
this.revertParentOverscroll();
|
|
184
|
+
this._parentScroll = value;
|
|
185
|
+
this.addScrollEventHandlers();
|
|
186
|
+
const scrollElement = this.getScrollElement();
|
|
187
|
+
if (this.modifyOverflowStyleOfParentScroll && scrollElement !== this.element.nativeElement) {
|
|
188
|
+
this.oldParentScrollOverflow = { x: scrollElement.style['overflow-x'], y: scrollElement.style['overflow-y'] };
|
|
189
|
+
scrollElement.style['overflow-y'] = this.horizontal ? 'visible' : 'auto';
|
|
190
|
+
scrollElement.style['overflow-x'] = this.horizontal ? 'auto' : 'visible';
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
ngOnInit() {
|
|
194
|
+
this.addScrollEventHandlers();
|
|
195
|
+
}
|
|
196
|
+
ngOnDestroy() {
|
|
197
|
+
this.removeScrollEventHandlers();
|
|
198
|
+
this.revertParentOverscroll();
|
|
199
|
+
}
|
|
200
|
+
ngOnChanges(changes) {
|
|
201
|
+
const indexLengthChanged = this.cachedItemsLength !== this.items.length;
|
|
202
|
+
this.cachedItemsLength = this.items.length;
|
|
203
|
+
const firstRun = !changes.items || !changes.items.previousValue || changes.items.previousValue.length === 0;
|
|
204
|
+
this.refresh_internal(indexLengthChanged || firstRun);
|
|
205
|
+
}
|
|
206
|
+
ngDoCheck() {
|
|
207
|
+
if (this.cachedItemsLength !== this.items.length) {
|
|
208
|
+
this.cachedItemsLength = this.items.length;
|
|
209
|
+
this.refresh_internal(true);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
if (this.previousViewPort && this.viewPortItems && this.viewPortItems.length > 0) {
|
|
213
|
+
let itemsArrayChanged = false;
|
|
214
|
+
for (let i = 0; i < this.viewPortItems.length; ++i) {
|
|
215
|
+
if (!this.compareItems(this.items[this.previousViewPort.startIndexWithBuffer + i], this.viewPortItems[i])) {
|
|
216
|
+
itemsArrayChanged = true;
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
if (itemsArrayChanged) {
|
|
221
|
+
this.refresh_internal(true);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
refresh(refreshCompletedCallback = undefined) {
|
|
226
|
+
this.refresh_internal(true, refreshCompletedCallback);
|
|
227
|
+
}
|
|
228
|
+
invalidateAllCachedMeasurements() {
|
|
229
|
+
this.wrapGroupDimensions = {
|
|
230
|
+
maxChildSizePerWrapGroup: [],
|
|
231
|
+
numberOfKnownWrapGroupChildSizes: 0,
|
|
232
|
+
sumOfKnownWrapGroupChildWidths: 0,
|
|
233
|
+
sumOfKnownWrapGroupChildHeights: 0
|
|
234
|
+
};
|
|
235
|
+
this.minMeasuredChildWidth = undefined;
|
|
236
|
+
this.minMeasuredChildHeight = undefined;
|
|
237
|
+
this.refresh_internal(false);
|
|
238
|
+
}
|
|
239
|
+
invalidateCachedMeasurementForItem(item) {
|
|
240
|
+
if (this.enableUnequalChildrenSizes) {
|
|
241
|
+
const index = this.items && this.items.indexOf(item);
|
|
242
|
+
if (index >= 0) {
|
|
243
|
+
this.invalidateCachedMeasurementAtIndex(index);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
this.minMeasuredChildWidth = undefined;
|
|
248
|
+
this.minMeasuredChildHeight = undefined;
|
|
249
|
+
}
|
|
250
|
+
this.refresh_internal(false);
|
|
251
|
+
}
|
|
252
|
+
invalidateCachedMeasurementAtIndex(index) {
|
|
253
|
+
if (this.enableUnequalChildrenSizes) {
|
|
254
|
+
const cachedMeasurement = this.wrapGroupDimensions.maxChildSizePerWrapGroup[index];
|
|
255
|
+
if (cachedMeasurement) {
|
|
256
|
+
this.wrapGroupDimensions.maxChildSizePerWrapGroup[index] = undefined;
|
|
257
|
+
--this.wrapGroupDimensions.numberOfKnownWrapGroupChildSizes;
|
|
258
|
+
this.wrapGroupDimensions.sumOfKnownWrapGroupChildWidths -= cachedMeasurement.childWidth || 0;
|
|
259
|
+
this.wrapGroupDimensions.sumOfKnownWrapGroupChildHeights -= cachedMeasurement.childHeight || 0;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
this.minMeasuredChildWidth = undefined;
|
|
264
|
+
this.minMeasuredChildHeight = undefined;
|
|
265
|
+
}
|
|
266
|
+
this.refresh_internal(false);
|
|
267
|
+
}
|
|
268
|
+
scrollInto(item, alignToBeginning = true, additionalOffset = 0, animationMilliseconds = undefined, animationCompletedCallback = undefined) {
|
|
269
|
+
const index = this.items.indexOf(item);
|
|
270
|
+
if (index === -1) {
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
this.scrollToIndex(index, alignToBeginning, additionalOffset, animationMilliseconds, animationCompletedCallback);
|
|
274
|
+
}
|
|
275
|
+
scrollToIndex(index, alignToBeginning = true, additionalOffset = 0, animationMilliseconds = undefined, animationCompletedCallback = undefined) {
|
|
276
|
+
let maxRetries = 5;
|
|
277
|
+
const retryIfNeeded = () => {
|
|
278
|
+
--maxRetries;
|
|
279
|
+
if (maxRetries <= 0) {
|
|
280
|
+
if (animationCompletedCallback) {
|
|
281
|
+
animationCompletedCallback();
|
|
282
|
+
}
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
const dimensions = this.calculateDimensions();
|
|
286
|
+
const desiredStartIndex = Math.min(Math.max(index, 0), dimensions.itemCount - 1);
|
|
287
|
+
if (this.previousViewPort.startIndex === desiredStartIndex) {
|
|
288
|
+
if (animationCompletedCallback) {
|
|
289
|
+
animationCompletedCallback();
|
|
290
|
+
}
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
this.scrollToIndex_internal(index, alignToBeginning, additionalOffset, 0, retryIfNeeded);
|
|
294
|
+
};
|
|
295
|
+
this.scrollToIndex_internal(index, alignToBeginning, additionalOffset, animationMilliseconds, retryIfNeeded);
|
|
296
|
+
}
|
|
297
|
+
scrollToIndex_internal(index, alignToBeginning = true, additionalOffset = 0, animationMilliseconds = undefined, animationCompletedCallback = undefined) {
|
|
298
|
+
animationMilliseconds = animationMilliseconds === undefined ? this.scrollAnimationTime : animationMilliseconds;
|
|
299
|
+
const dimensions = this.calculateDimensions();
|
|
300
|
+
let scroll = this.calculatePadding(index, dimensions) + additionalOffset;
|
|
301
|
+
if (!alignToBeginning) {
|
|
302
|
+
scroll -= dimensions.wrapGroupsPerPage * dimensions[this._childScrollDim];
|
|
303
|
+
}
|
|
304
|
+
this.scrollToPosition(scroll, animationMilliseconds, animationCompletedCallback);
|
|
305
|
+
}
|
|
306
|
+
scrollToPosition(scrollPosition, animationMilliseconds = undefined, animationCompletedCallback = undefined) {
|
|
307
|
+
scrollPosition += this.getElementsOffset();
|
|
308
|
+
animationMilliseconds = animationMilliseconds === undefined ? this.scrollAnimationTime : animationMilliseconds;
|
|
309
|
+
const scrollElement = this.getScrollElement();
|
|
310
|
+
let animationRequest;
|
|
311
|
+
if (this.currentTween) {
|
|
312
|
+
this.currentTween.stop();
|
|
313
|
+
this.currentTween = undefined;
|
|
314
|
+
}
|
|
315
|
+
if (!animationMilliseconds) {
|
|
316
|
+
this.renderer.setProperty(scrollElement, this._scrollType, scrollPosition);
|
|
317
|
+
this.refresh_internal(false, animationCompletedCallback);
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
const tweenConfigObj = { scrollPosition: scrollElement[this._scrollType] };
|
|
321
|
+
const newTween = new tween.Tween(tweenConfigObj)
|
|
322
|
+
.to({ scrollPosition }, animationMilliseconds)
|
|
323
|
+
.easing(tween.Easing.Quadratic.Out)
|
|
324
|
+
.onUpdate((data) => {
|
|
325
|
+
if (isNaN(data.scrollPosition)) {
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
this.renderer.setProperty(scrollElement, this._scrollType, data.scrollPosition);
|
|
329
|
+
this.refresh_internal(false);
|
|
330
|
+
})
|
|
331
|
+
.onStop(() => {
|
|
332
|
+
cancelAnimationFrame(animationRequest);
|
|
333
|
+
})
|
|
334
|
+
.start();
|
|
335
|
+
const animate = (time) => {
|
|
336
|
+
if (!newTween["isPlaying"]()) {
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
newTween.update(time);
|
|
340
|
+
if (tweenConfigObj.scrollPosition === scrollPosition) {
|
|
341
|
+
this.refresh_internal(false, animationCompletedCallback);
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
this.zone.runOutsideAngular(() => {
|
|
345
|
+
animationRequest = requestAnimationFrame(animate);
|
|
346
|
+
});
|
|
347
|
+
};
|
|
348
|
+
animate();
|
|
349
|
+
this.currentTween = newTween;
|
|
350
|
+
}
|
|
351
|
+
getElementSize(element) {
|
|
352
|
+
const result = element.getBoundingClientRect();
|
|
353
|
+
const styles = getComputedStyle(element);
|
|
354
|
+
const marginTop = parseInt(styles['margin-top'], 10) || 0;
|
|
355
|
+
const marginBottom = parseInt(styles['margin-bottom'], 10) || 0;
|
|
356
|
+
const marginLeft = parseInt(styles['margin-left'], 10) || 0;
|
|
357
|
+
const marginRight = parseInt(styles['margin-right'], 10) || 0;
|
|
358
|
+
return {
|
|
359
|
+
top: result.top + marginTop,
|
|
360
|
+
bottom: result.bottom + marginBottom,
|
|
361
|
+
left: result.left + marginLeft,
|
|
362
|
+
right: result.right + marginRight,
|
|
363
|
+
width: parseFloat((result.width + marginLeft + marginRight).toFixed(3)),
|
|
364
|
+
height: parseFloat((result.height + marginTop + marginBottom).toFixed(3))
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
getContent() {
|
|
368
|
+
const content = (this.containerElementRef && this.containerElementRef.nativeElement) || this.contentElementRef.nativeElement;
|
|
369
|
+
return content;
|
|
370
|
+
}
|
|
371
|
+
checkScrollElementResized() {
|
|
372
|
+
const boundingRect = this.getElementSize(this.getScrollElement());
|
|
373
|
+
let sizeChanged;
|
|
374
|
+
if (!this.previousScrollBoundingRect) {
|
|
375
|
+
sizeChanged = true;
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
const widthChange = Math.abs(boundingRect.width - this.previousScrollBoundingRect.width);
|
|
379
|
+
const heightChange = Math.abs(boundingRect.height - this.previousScrollBoundingRect.height);
|
|
380
|
+
sizeChanged = widthChange > this.resizeBypassRefreshThreshold || heightChange > this.resizeBypassRefreshThreshold;
|
|
381
|
+
}
|
|
382
|
+
if (sizeChanged) {
|
|
383
|
+
this.previousScrollBoundingRect = boundingRect;
|
|
384
|
+
if (boundingRect.width > 0 && boundingRect.height > 0) {
|
|
385
|
+
this.refresh_internal(false);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
updateDirection() {
|
|
390
|
+
if (this.horizontal) {
|
|
391
|
+
this._childScrollDim = 'childWidth';
|
|
392
|
+
this._invisiblePaddingProperty = 'scaleX';
|
|
393
|
+
this._marginDir = 'margin-left';
|
|
394
|
+
this._offsetType = 'offsetLeft';
|
|
395
|
+
this._pageOffsetType = 'pageXOffset';
|
|
396
|
+
this._scrollType = 'scrollLeft';
|
|
397
|
+
this._translateDir = 'translateX';
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
this._childScrollDim = 'childHeight';
|
|
401
|
+
this._invisiblePaddingProperty = 'scaleY';
|
|
402
|
+
this._marginDir = 'margin-top';
|
|
403
|
+
this._offsetType = 'offsetTop';
|
|
404
|
+
this._pageOffsetType = 'pageYOffset';
|
|
405
|
+
this._scrollType = 'scrollTop';
|
|
406
|
+
this._translateDir = 'translateY';
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
debounce(func, wait, ...args) {
|
|
410
|
+
const throttled = this.throttleTrailing(func, wait);
|
|
411
|
+
const result = function () {
|
|
412
|
+
throttled['cancel']();
|
|
413
|
+
throttled.apply(this, args);
|
|
414
|
+
};
|
|
415
|
+
result['cancel'] = function () {
|
|
416
|
+
throttled['cancel']();
|
|
417
|
+
};
|
|
418
|
+
return result;
|
|
419
|
+
}
|
|
420
|
+
throttleTrailing(func, wait, ...args) {
|
|
421
|
+
let timeout = undefined;
|
|
422
|
+
let _arguments = args;
|
|
423
|
+
const result = function () {
|
|
424
|
+
const _this = this;
|
|
425
|
+
_arguments = args;
|
|
426
|
+
if (timeout) {
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
if (wait <= 0) {
|
|
430
|
+
func.apply(_this, _arguments);
|
|
431
|
+
}
|
|
432
|
+
else {
|
|
433
|
+
timeout = setTimeout(function () {
|
|
434
|
+
timeout = undefined;
|
|
435
|
+
func.apply(_this, _arguments);
|
|
436
|
+
}, wait);
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
result['cancel'] = function () {
|
|
440
|
+
if (timeout) {
|
|
441
|
+
clearTimeout(timeout);
|
|
442
|
+
timeout = undefined;
|
|
443
|
+
}
|
|
444
|
+
};
|
|
445
|
+
return result;
|
|
446
|
+
}
|
|
447
|
+
refresh_internal(itemsArrayModified, refreshCompletedCallback = undefined, maxRunTimes = 2) {
|
|
448
|
+
//note: maxRunTimes is to force it to keep recalculating if the previous iteration caused a re-render (different sliced items in viewport or scrollPosition changed).
|
|
449
|
+
//The default of 2x max will probably be accurate enough without causing too large a performance bottleneck
|
|
450
|
+
//The code would typically quit out on the 2nd iteration anyways. The main time it'd think more than 2 runs would be necessary would be for vastly different sized child items or if this is the 1st time the items array was initialized.
|
|
451
|
+
//Without maxRunTimes, If the user is actively scrolling this code would become an infinite loop until they stopped scrolling. This would be okay, except each scroll event would start an additional infinte loop. We want to short-circuit it to prevent this.
|
|
452
|
+
if (itemsArrayModified && this.previousViewPort && this.previousViewPort.scrollStartPosition > 0) {
|
|
453
|
+
//if items were prepended, scroll forward to keep same items visible
|
|
454
|
+
const oldViewPort = this.previousViewPort;
|
|
455
|
+
const oldViewPortItems = this.viewPortItems;
|
|
456
|
+
const oldRefreshCompletedCallback = refreshCompletedCallback;
|
|
457
|
+
refreshCompletedCallback = () => {
|
|
458
|
+
const scrollLengthDelta = this.previousViewPort.scrollLength - oldViewPort.scrollLength;
|
|
459
|
+
if (scrollLengthDelta > 0 && this.viewPortItems) {
|
|
460
|
+
const oldStartItem = oldViewPortItems[0];
|
|
461
|
+
const oldStartItemIndex = this.items.findIndex(x => this.compareItems(oldStartItem, x));
|
|
462
|
+
if (oldStartItemIndex > this.previousViewPort.startIndexWithBuffer) {
|
|
463
|
+
let itemOrderChanged = false;
|
|
464
|
+
for (let i = 1; i < this.viewPortItems.length; ++i) {
|
|
465
|
+
if (!this.compareItems(this.items[oldStartItemIndex + i], oldViewPortItems[i])) {
|
|
466
|
+
itemOrderChanged = true;
|
|
467
|
+
break;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
if (!itemOrderChanged) {
|
|
471
|
+
this.scrollToPosition(this.previousViewPort.scrollStartPosition + scrollLengthDelta, 0, oldRefreshCompletedCallback);
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
if (oldRefreshCompletedCallback) {
|
|
477
|
+
oldRefreshCompletedCallback();
|
|
478
|
+
}
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
this.zone.runOutsideAngular(() => {
|
|
482
|
+
requestAnimationFrame(() => {
|
|
483
|
+
if (itemsArrayModified) {
|
|
484
|
+
this.resetWrapGroupDimensions();
|
|
485
|
+
}
|
|
486
|
+
const viewport = this.calculateViewport();
|
|
487
|
+
const startChanged = itemsArrayModified || viewport.startIndex !== this.previousViewPort.startIndex;
|
|
488
|
+
const endChanged = itemsArrayModified || viewport.endIndex !== this.previousViewPort.endIndex;
|
|
489
|
+
const scrollLengthChanged = viewport.scrollLength !== this.previousViewPort.scrollLength;
|
|
490
|
+
const paddingChanged = viewport.padding !== this.previousViewPort.padding;
|
|
491
|
+
const scrollPositionChanged = viewport.scrollStartPosition !== this.previousViewPort.scrollStartPosition || viewport.scrollEndPosition !== this.previousViewPort.scrollEndPosition || viewport.maxScrollPosition !== this.previousViewPort.maxScrollPosition;
|
|
492
|
+
const scrollDirection = this.previousViewPort.endIndex <= viewport.endIndex ? 'forward' : 'backward';
|
|
493
|
+
this.previousViewPort = viewport;
|
|
494
|
+
if (scrollLengthChanged) {
|
|
495
|
+
this.renderer.setStyle(this.invisiblePaddingElementRef.nativeElement, 'transform', `${this._invisiblePaddingProperty}(${viewport.scrollLength})`);
|
|
496
|
+
this.renderer.setStyle(this.invisiblePaddingElementRef.nativeElement, 'webkitTransform', `${this._invisiblePaddingProperty}(${viewport.scrollLength})`);
|
|
497
|
+
}
|
|
498
|
+
if (paddingChanged) {
|
|
499
|
+
if (this.useMarginInsteadOfTranslate) {
|
|
500
|
+
this.renderer.setStyle(this.contentElementRef.nativeElement, this._marginDir, `${viewport.padding}px`);
|
|
501
|
+
}
|
|
502
|
+
else {
|
|
503
|
+
this.renderer.setStyle(this.contentElementRef.nativeElement, 'transform', `${this._translateDir}(${viewport.padding}px)`);
|
|
504
|
+
this.renderer.setStyle(this.contentElementRef.nativeElement, 'webkitTransform', `${this._translateDir}(${viewport.padding}px)`);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
if (this.headerElementRef) {
|
|
508
|
+
const scrollPosition = this.getScrollElement()[this._scrollType];
|
|
509
|
+
const containerOffset = this.getElementsOffset();
|
|
510
|
+
const offset = Math.max(scrollPosition - viewport.padding - containerOffset + this.headerElementRef.nativeElement.clientHeight, 0);
|
|
511
|
+
this.renderer.setStyle(this.headerElementRef.nativeElement, 'transform', `${this._translateDir}(${offset}px)`);
|
|
512
|
+
this.renderer.setStyle(this.headerElementRef.nativeElement, 'webkitTransform', `${this._translateDir}(${offset}px)`);
|
|
513
|
+
}
|
|
514
|
+
const changeEventArg = (startChanged || endChanged) ? {
|
|
515
|
+
startIndex: viewport.startIndex,
|
|
516
|
+
endIndex: viewport.endIndex,
|
|
517
|
+
scrollStartPosition: viewport.scrollStartPosition,
|
|
518
|
+
scrollEndPosition: viewport.scrollEndPosition,
|
|
519
|
+
scrollDirection: scrollDirection,
|
|
520
|
+
startIndexWithBuffer: viewport.startIndexWithBuffer,
|
|
521
|
+
endIndexWithBuffer: viewport.endIndexWithBuffer,
|
|
522
|
+
maxScrollPosition: viewport.maxScrollPosition,
|
|
523
|
+
} : undefined;
|
|
524
|
+
if (startChanged || endChanged || scrollPositionChanged) {
|
|
525
|
+
const handleChanged = () => {
|
|
526
|
+
// update the scroll list to trigger re-render of components in viewport
|
|
527
|
+
this.viewPortItems = viewport.startIndexWithBuffer >= 0 && viewport.endIndexWithBuffer >= 0 ? this.items.slice(viewport.startIndexWithBuffer, viewport.endIndexWithBuffer + 1) : [];
|
|
528
|
+
this.vsUpdate.emit(this.viewPortItems);
|
|
529
|
+
if (startChanged) {
|
|
530
|
+
this.vsStart.emit(changeEventArg);
|
|
531
|
+
}
|
|
532
|
+
if (endChanged) {
|
|
533
|
+
this.vsEnd.emit(changeEventArg);
|
|
534
|
+
}
|
|
535
|
+
if (startChanged || endChanged) {
|
|
536
|
+
this.changeDetectorRef.markForCheck();
|
|
537
|
+
this.vsChange.emit(changeEventArg);
|
|
538
|
+
}
|
|
539
|
+
if (maxRunTimes > 0) {
|
|
540
|
+
this.refresh_internal(false, refreshCompletedCallback, maxRunTimes - 1);
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
if (refreshCompletedCallback) {
|
|
544
|
+
refreshCompletedCallback();
|
|
545
|
+
}
|
|
546
|
+
};
|
|
547
|
+
if (this.executeRefreshOutsideAngularZone) {
|
|
548
|
+
handleChanged();
|
|
549
|
+
}
|
|
550
|
+
else {
|
|
551
|
+
this.zone.run(handleChanged);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
else {
|
|
555
|
+
if (maxRunTimes > 0 && (scrollLengthChanged || paddingChanged)) {
|
|
556
|
+
this.refresh_internal(false, refreshCompletedCallback, maxRunTimes - 1);
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
if (refreshCompletedCallback) {
|
|
560
|
+
refreshCompletedCallback();
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
});
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
getScrollElement() {
|
|
567
|
+
return this.parentScroll instanceof Window ? document.scrollingElement || document.documentElement || document.body : this.parentScroll || this.element.nativeElement;
|
|
568
|
+
}
|
|
569
|
+
addScrollEventHandlers() {
|
|
570
|
+
if (this.isAngularUniversalSSR) {
|
|
571
|
+
return;
|
|
572
|
+
}
|
|
573
|
+
const scrollElement = this.getScrollElement();
|
|
574
|
+
this.removeScrollEventHandlers();
|
|
575
|
+
this.zone.runOutsideAngular(() => {
|
|
576
|
+
if (this.parentScroll instanceof Window) {
|
|
577
|
+
this.disposeScrollHandler = this.renderer.listen('window', 'scroll', this.onScroll);
|
|
578
|
+
this.disposeResizeHandler = this.renderer.listen('window', 'resize', this.onScroll);
|
|
579
|
+
}
|
|
580
|
+
else {
|
|
581
|
+
this.disposeScrollHandler = this.renderer.listen(scrollElement, 'scroll', this.onScroll);
|
|
582
|
+
if (this._checkResizeInterval > 0) {
|
|
583
|
+
this.checkScrollElementResizedTimer = setInterval(() => { this.checkScrollElementResized(); }, this._checkResizeInterval);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
removeScrollEventHandlers() {
|
|
589
|
+
if (this.checkScrollElementResizedTimer) {
|
|
590
|
+
clearInterval(this.checkScrollElementResizedTimer);
|
|
591
|
+
}
|
|
592
|
+
if (this.disposeScrollHandler) {
|
|
593
|
+
this.disposeScrollHandler();
|
|
594
|
+
this.disposeScrollHandler = undefined;
|
|
595
|
+
}
|
|
596
|
+
if (this.disposeResizeHandler) {
|
|
597
|
+
this.disposeResizeHandler();
|
|
598
|
+
this.disposeResizeHandler = undefined;
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
getElementsOffset() {
|
|
602
|
+
if (this.isAngularUniversalSSR) {
|
|
603
|
+
return 0;
|
|
604
|
+
}
|
|
605
|
+
let offset = 0;
|
|
606
|
+
if (this.containerElementRef && this.containerElementRef.nativeElement) {
|
|
607
|
+
offset += this.containerElementRef.nativeElement[this._offsetType];
|
|
608
|
+
}
|
|
609
|
+
if (this.parentScroll) {
|
|
610
|
+
const scrollElement = this.getScrollElement();
|
|
611
|
+
const elementClientRect = this.getElementSize(this.element.nativeElement);
|
|
612
|
+
const scrollClientRect = this.getElementSize(scrollElement);
|
|
613
|
+
if (this.horizontal) {
|
|
614
|
+
offset += elementClientRect.left - scrollClientRect.left;
|
|
615
|
+
}
|
|
616
|
+
else {
|
|
617
|
+
offset += elementClientRect.top - scrollClientRect.top;
|
|
618
|
+
}
|
|
619
|
+
if (!(this.parentScroll instanceof Window)) {
|
|
620
|
+
offset += scrollElement[this._scrollType];
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
return offset;
|
|
624
|
+
}
|
|
625
|
+
countItemsPerWrapGroup() {
|
|
626
|
+
if (this.isAngularUniversalSSR) {
|
|
627
|
+
return Math.round(this.horizontal ? this.ssrViewportHeight / this.ssrChildHeight : this.ssrViewportWidth / this.ssrChildWidth);
|
|
628
|
+
}
|
|
629
|
+
const propertyName = this.horizontal ? 'offsetLeft' : 'offsetTop';
|
|
630
|
+
const children = this.getContent().children;
|
|
631
|
+
const childrenLength = children ? children.length : 0;
|
|
632
|
+
if (childrenLength === 0) {
|
|
633
|
+
return 1;
|
|
634
|
+
}
|
|
635
|
+
const firstOffset = children[0][propertyName];
|
|
636
|
+
let result = 1;
|
|
637
|
+
while (result < childrenLength && firstOffset === children[result][propertyName]) {
|
|
638
|
+
++result;
|
|
639
|
+
}
|
|
640
|
+
return result;
|
|
641
|
+
}
|
|
642
|
+
getScrollStartPosition() {
|
|
643
|
+
let windowScrollValue = undefined;
|
|
644
|
+
if (this.parentScroll instanceof Window) {
|
|
645
|
+
windowScrollValue = window[this._pageOffsetType];
|
|
646
|
+
}
|
|
647
|
+
return windowScrollValue || this.getScrollElement()[this._scrollType] || 0;
|
|
648
|
+
}
|
|
649
|
+
resetWrapGroupDimensions() {
|
|
650
|
+
const oldWrapGroupDimensions = this.wrapGroupDimensions;
|
|
651
|
+
this.invalidateAllCachedMeasurements();
|
|
652
|
+
if (!this.enableUnequalChildrenSizes || !oldWrapGroupDimensions || oldWrapGroupDimensions.numberOfKnownWrapGroupChildSizes === 0) {
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
const itemsPerWrapGroup = this.countItemsPerWrapGroup();
|
|
656
|
+
for (let wrapGroupIndex = 0; wrapGroupIndex < oldWrapGroupDimensions.maxChildSizePerWrapGroup.length; ++wrapGroupIndex) {
|
|
657
|
+
const oldWrapGroupDimension = oldWrapGroupDimensions.maxChildSizePerWrapGroup[wrapGroupIndex];
|
|
658
|
+
if (!oldWrapGroupDimension || !oldWrapGroupDimension.items || !oldWrapGroupDimension.items.length) {
|
|
659
|
+
continue;
|
|
660
|
+
}
|
|
661
|
+
if (oldWrapGroupDimension.items.length !== itemsPerWrapGroup) {
|
|
662
|
+
return;
|
|
663
|
+
}
|
|
664
|
+
let itemsChanged = false;
|
|
665
|
+
const arrayStartIndex = itemsPerWrapGroup * wrapGroupIndex;
|
|
666
|
+
for (let i = 0; i < itemsPerWrapGroup; ++i) {
|
|
667
|
+
if (!this.compareItems(oldWrapGroupDimension.items[i], this.items[arrayStartIndex + i])) {
|
|
668
|
+
itemsChanged = true;
|
|
669
|
+
break;
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
if (!itemsChanged) {
|
|
673
|
+
++this.wrapGroupDimensions.numberOfKnownWrapGroupChildSizes;
|
|
674
|
+
this.wrapGroupDimensions.sumOfKnownWrapGroupChildWidths += oldWrapGroupDimension.childWidth || 0;
|
|
675
|
+
this.wrapGroupDimensions.sumOfKnownWrapGroupChildHeights += oldWrapGroupDimension.childHeight || 0;
|
|
676
|
+
this.wrapGroupDimensions.maxChildSizePerWrapGroup[wrapGroupIndex] = oldWrapGroupDimension;
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
calculateDimensions() {
|
|
681
|
+
const scrollElement = this.getScrollElement();
|
|
682
|
+
const maxCalculatedScrollBarSize = 25; // Note: Formula to auto-calculate doesn't work for ParentScroll, so we default to this if not set by consuming application
|
|
683
|
+
this.calculatedScrollbarHeight = Math.max(Math.min(scrollElement.offsetHeight - scrollElement.clientHeight, maxCalculatedScrollBarSize), this.calculatedScrollbarHeight);
|
|
684
|
+
this.calculatedScrollbarWidth = Math.max(Math.min(scrollElement.offsetWidth - scrollElement.clientWidth, maxCalculatedScrollBarSize), this.calculatedScrollbarWidth);
|
|
685
|
+
let viewportWidth = scrollElement.offsetWidth - (this.scrollbarWidth || this.calculatedScrollbarWidth || (this.horizontal ? 0 : maxCalculatedScrollBarSize));
|
|
686
|
+
let viewportHeight = scrollElement.offsetHeight - (this.scrollbarHeight || this.calculatedScrollbarHeight || (this.horizontal ? maxCalculatedScrollBarSize : 0));
|
|
687
|
+
const content = this.getContent();
|
|
688
|
+
const itemsPerWrapGroup = this.countItemsPerWrapGroup();
|
|
689
|
+
let wrapGroupsPerPage;
|
|
690
|
+
let defaultChildWidth;
|
|
691
|
+
let defaultChildHeight;
|
|
692
|
+
if (this.isAngularUniversalSSR) {
|
|
693
|
+
viewportWidth = this.ssrViewportWidth;
|
|
694
|
+
viewportHeight = this.ssrViewportHeight;
|
|
695
|
+
defaultChildWidth = this.ssrChildWidth;
|
|
696
|
+
defaultChildHeight = this.ssrChildHeight;
|
|
697
|
+
const itemsPerRow = Math.max(Math.ceil(viewportWidth / defaultChildWidth), 1);
|
|
698
|
+
const itemsPerCol = Math.max(Math.ceil(viewportHeight / defaultChildHeight), 1);
|
|
699
|
+
wrapGroupsPerPage = this.horizontal ? itemsPerRow : itemsPerCol;
|
|
700
|
+
}
|
|
701
|
+
else if (!this.enableUnequalChildrenSizes) {
|
|
702
|
+
if (content.children.length > 0) {
|
|
703
|
+
if (!this.childWidth || !this.childHeight) {
|
|
704
|
+
if (!this.minMeasuredChildWidth && viewportWidth > 0) {
|
|
705
|
+
this.minMeasuredChildWidth = viewportWidth;
|
|
706
|
+
}
|
|
707
|
+
if (!this.minMeasuredChildHeight && viewportHeight > 0) {
|
|
708
|
+
this.minMeasuredChildHeight = viewportHeight;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
const child = content.children[0];
|
|
712
|
+
const clientRect = this.getElementSize(child);
|
|
713
|
+
this.minMeasuredChildWidth = Math.min(this.minMeasuredChildWidth, clientRect.width);
|
|
714
|
+
this.minMeasuredChildHeight = Math.min(this.minMeasuredChildHeight, clientRect.height);
|
|
715
|
+
// Added for getting the child height (for card view, return all the clientRect object).
|
|
716
|
+
// if (this._lastChildRect === null ||
|
|
717
|
+
// (clientRect?.height !== 0 && (
|
|
718
|
+
// Math.round(this._lastChildRect?.height) !== Math.round(clientRect?.height) ||
|
|
719
|
+
// Math.round(this._lastChildRect?.width) !== Math.round(clientRect?.width))
|
|
720
|
+
// )) {
|
|
721
|
+
// this._lastChildRect = clientRect;
|
|
722
|
+
// this.vsChildRectChange.emit(clientRect);
|
|
723
|
+
// }
|
|
724
|
+
}
|
|
725
|
+
defaultChildWidth = this.childWidth || this.minMeasuredChildWidth || viewportWidth;
|
|
726
|
+
defaultChildHeight = this.childHeight || this.minMeasuredChildHeight || viewportHeight;
|
|
727
|
+
const itemsPerRow = Math.max(Math.ceil(viewportWidth / defaultChildWidth), 1);
|
|
728
|
+
const itemsPerCol = Math.max(Math.ceil(viewportHeight / defaultChildHeight), 1);
|
|
729
|
+
wrapGroupsPerPage = this.horizontal ? itemsPerRow : itemsPerCol;
|
|
730
|
+
}
|
|
731
|
+
else {
|
|
732
|
+
let scrollOffset = scrollElement[this._scrollType] - (this.previousViewPort ? this.previousViewPort.padding : 0);
|
|
733
|
+
let arrayStartIndex = this.previousViewPort.startIndexWithBuffer || 0;
|
|
734
|
+
let wrapGroupIndex = Math.ceil(arrayStartIndex / itemsPerWrapGroup);
|
|
735
|
+
let maxWidthForWrapGroup = 0;
|
|
736
|
+
let maxHeightForWrapGroup = 0;
|
|
737
|
+
let sumOfVisibleMaxWidths = 0;
|
|
738
|
+
let sumOfVisibleMaxHeights = 0;
|
|
739
|
+
wrapGroupsPerPage = 0;
|
|
740
|
+
for (let i = 0; i < content.children.length; ++i) {
|
|
741
|
+
++arrayStartIndex;
|
|
742
|
+
const child = content.children[i];
|
|
743
|
+
const clientRect = this.getElementSize(child);
|
|
744
|
+
maxWidthForWrapGroup = Math.max(maxWidthForWrapGroup, clientRect.width);
|
|
745
|
+
maxHeightForWrapGroup = Math.max(maxHeightForWrapGroup, clientRect.height);
|
|
746
|
+
if (arrayStartIndex % itemsPerWrapGroup === 0) {
|
|
747
|
+
const oldValue = this.wrapGroupDimensions.maxChildSizePerWrapGroup[wrapGroupIndex];
|
|
748
|
+
if (oldValue) {
|
|
749
|
+
--this.wrapGroupDimensions.numberOfKnownWrapGroupChildSizes;
|
|
750
|
+
this.wrapGroupDimensions.sumOfKnownWrapGroupChildWidths -= oldValue.childWidth || 0;
|
|
751
|
+
this.wrapGroupDimensions.sumOfKnownWrapGroupChildHeights -= oldValue.childHeight || 0;
|
|
752
|
+
}
|
|
753
|
+
++this.wrapGroupDimensions.numberOfKnownWrapGroupChildSizes;
|
|
754
|
+
const items = this.items.slice(arrayStartIndex - itemsPerWrapGroup, arrayStartIndex);
|
|
755
|
+
this.wrapGroupDimensions.maxChildSizePerWrapGroup[wrapGroupIndex] = {
|
|
756
|
+
childWidth: maxWidthForWrapGroup,
|
|
757
|
+
childHeight: maxHeightForWrapGroup,
|
|
758
|
+
items: items
|
|
759
|
+
};
|
|
760
|
+
this.wrapGroupDimensions.sumOfKnownWrapGroupChildWidths += maxWidthForWrapGroup;
|
|
761
|
+
this.wrapGroupDimensions.sumOfKnownWrapGroupChildHeights += maxHeightForWrapGroup;
|
|
762
|
+
if (this.horizontal) {
|
|
763
|
+
let maxVisibleWidthForWrapGroup = Math.min(maxWidthForWrapGroup, Math.max(viewportWidth - sumOfVisibleMaxWidths, 0));
|
|
764
|
+
if (scrollOffset > 0) {
|
|
765
|
+
const scrollOffsetToRemove = Math.min(scrollOffset, maxVisibleWidthForWrapGroup);
|
|
766
|
+
maxVisibleWidthForWrapGroup -= scrollOffsetToRemove;
|
|
767
|
+
scrollOffset -= scrollOffsetToRemove;
|
|
768
|
+
}
|
|
769
|
+
sumOfVisibleMaxWidths += maxVisibleWidthForWrapGroup;
|
|
770
|
+
if (maxVisibleWidthForWrapGroup > 0 && viewportWidth >= sumOfVisibleMaxWidths) {
|
|
771
|
+
++wrapGroupsPerPage;
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
else {
|
|
775
|
+
let maxVisibleHeightForWrapGroup = Math.min(maxHeightForWrapGroup, Math.max(viewportHeight - sumOfVisibleMaxHeights, 0));
|
|
776
|
+
if (scrollOffset > 0) {
|
|
777
|
+
const scrollOffsetToRemove = Math.min(scrollOffset, maxVisibleHeightForWrapGroup);
|
|
778
|
+
maxVisibleHeightForWrapGroup -= scrollOffsetToRemove;
|
|
779
|
+
scrollOffset -= scrollOffsetToRemove;
|
|
780
|
+
}
|
|
781
|
+
sumOfVisibleMaxHeights += maxVisibleHeightForWrapGroup;
|
|
782
|
+
if (maxVisibleHeightForWrapGroup > 0 && viewportHeight >= sumOfVisibleMaxHeights) {
|
|
783
|
+
++wrapGroupsPerPage;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
++wrapGroupIndex;
|
|
787
|
+
maxWidthForWrapGroup = 0;
|
|
788
|
+
maxHeightForWrapGroup = 0;
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
const averageChildWidth = this.wrapGroupDimensions.sumOfKnownWrapGroupChildWidths / this.wrapGroupDimensions.numberOfKnownWrapGroupChildSizes;
|
|
792
|
+
const averageChildHeight = this.wrapGroupDimensions.sumOfKnownWrapGroupChildHeights / this.wrapGroupDimensions.numberOfKnownWrapGroupChildSizes;
|
|
793
|
+
defaultChildWidth = this.childWidth || averageChildWidth || viewportWidth;
|
|
794
|
+
defaultChildHeight = this.childHeight || averageChildHeight || viewportHeight;
|
|
795
|
+
if (this.horizontal) {
|
|
796
|
+
if (viewportWidth > sumOfVisibleMaxWidths) {
|
|
797
|
+
wrapGroupsPerPage += Math.ceil((viewportWidth - sumOfVisibleMaxWidths) / defaultChildWidth);
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
else {
|
|
801
|
+
if (viewportHeight > sumOfVisibleMaxHeights) {
|
|
802
|
+
wrapGroupsPerPage += Math.ceil((viewportHeight - sumOfVisibleMaxHeights) / defaultChildHeight);
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
const itemCount = this.items.length;
|
|
807
|
+
const itemsPerPage = itemsPerWrapGroup * wrapGroupsPerPage;
|
|
808
|
+
const pageCount_fractional = itemCount / itemsPerPage;
|
|
809
|
+
const numberOfWrapGroups = Math.ceil(itemCount / itemsPerWrapGroup);
|
|
810
|
+
let scrollLength = 0;
|
|
811
|
+
const defaultScrollLengthPerWrapGroup = this.horizontal ? defaultChildWidth : defaultChildHeight;
|
|
812
|
+
if (this.enableUnequalChildrenSizes) {
|
|
813
|
+
let numUnknownChildSizes = 0;
|
|
814
|
+
for (let i = 0; i < numberOfWrapGroups; ++i) {
|
|
815
|
+
const childSize = this.wrapGroupDimensions.maxChildSizePerWrapGroup[i] && this.wrapGroupDimensions.maxChildSizePerWrapGroup[i][this._childScrollDim];
|
|
816
|
+
if (childSize) {
|
|
817
|
+
scrollLength += childSize;
|
|
818
|
+
}
|
|
819
|
+
else {
|
|
820
|
+
++numUnknownChildSizes;
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
scrollLength += Math.round(numUnknownChildSizes * defaultScrollLengthPerWrapGroup);
|
|
824
|
+
}
|
|
825
|
+
else {
|
|
826
|
+
scrollLength = numberOfWrapGroups * defaultScrollLengthPerWrapGroup;
|
|
827
|
+
}
|
|
828
|
+
if (this.headerElementRef) {
|
|
829
|
+
scrollLength += this.headerElementRef.nativeElement.clientHeight;
|
|
830
|
+
}
|
|
831
|
+
const viewportLength = this.horizontal ? viewportWidth : viewportHeight;
|
|
832
|
+
const maxScrollPosition = Math.max(scrollLength - viewportLength, 0);
|
|
833
|
+
return {
|
|
834
|
+
childHeight: defaultChildHeight,
|
|
835
|
+
childWidth: defaultChildWidth,
|
|
836
|
+
itemCount: itemCount,
|
|
837
|
+
itemsPerPage: itemsPerPage,
|
|
838
|
+
itemsPerWrapGroup: itemsPerWrapGroup,
|
|
839
|
+
maxScrollPosition: maxScrollPosition,
|
|
840
|
+
pageCount_fractional: pageCount_fractional,
|
|
841
|
+
scrollLength: scrollLength,
|
|
842
|
+
viewportLength: viewportLength,
|
|
843
|
+
wrapGroupsPerPage: wrapGroupsPerPage,
|
|
844
|
+
};
|
|
845
|
+
}
|
|
846
|
+
calculatePadding(arrayStartIndexWithBuffer, dimensions) {
|
|
847
|
+
if (dimensions.itemCount === 0) {
|
|
848
|
+
return 0;
|
|
849
|
+
}
|
|
850
|
+
const defaultScrollLengthPerWrapGroup = dimensions[this._childScrollDim];
|
|
851
|
+
const startingWrapGroupIndex = Math.floor(arrayStartIndexWithBuffer / dimensions.itemsPerWrapGroup) || 0;
|
|
852
|
+
if (!this.enableUnequalChildrenSizes) {
|
|
853
|
+
return defaultScrollLengthPerWrapGroup * startingWrapGroupIndex;
|
|
854
|
+
}
|
|
855
|
+
let numUnknownChildSizes = 0;
|
|
856
|
+
let result = 0;
|
|
857
|
+
for (let i = 0; i < startingWrapGroupIndex; ++i) {
|
|
858
|
+
const childSize = this.wrapGroupDimensions.maxChildSizePerWrapGroup[i] && this.wrapGroupDimensions.maxChildSizePerWrapGroup[i][this._childScrollDim];
|
|
859
|
+
if (childSize) {
|
|
860
|
+
result += childSize;
|
|
861
|
+
}
|
|
862
|
+
else {
|
|
863
|
+
++numUnknownChildSizes;
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
result += Math.round(numUnknownChildSizes * defaultScrollLengthPerWrapGroup);
|
|
867
|
+
return result;
|
|
868
|
+
}
|
|
869
|
+
calculatePageInfo(scrollPosition, dimensions) {
|
|
870
|
+
let scrollPercentage = 0;
|
|
871
|
+
if (this.enableUnequalChildrenSizes) {
|
|
872
|
+
const numberOfWrapGroups = Math.ceil(dimensions.itemCount / dimensions.itemsPerWrapGroup);
|
|
873
|
+
let totalScrolledLength = 0;
|
|
874
|
+
const defaultScrollLengthPerWrapGroup = dimensions[this._childScrollDim];
|
|
875
|
+
for (let i = 0; i < numberOfWrapGroups; ++i) {
|
|
876
|
+
const childSize = this.wrapGroupDimensions.maxChildSizePerWrapGroup[i] && this.wrapGroupDimensions.maxChildSizePerWrapGroup[i][this._childScrollDim];
|
|
877
|
+
if (childSize) {
|
|
878
|
+
totalScrolledLength += childSize;
|
|
879
|
+
}
|
|
880
|
+
else {
|
|
881
|
+
totalScrolledLength += defaultScrollLengthPerWrapGroup;
|
|
882
|
+
}
|
|
883
|
+
if (scrollPosition < totalScrolledLength) {
|
|
884
|
+
scrollPercentage = i / numberOfWrapGroups;
|
|
885
|
+
break;
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
else {
|
|
890
|
+
scrollPercentage = scrollPosition / dimensions.scrollLength;
|
|
891
|
+
}
|
|
892
|
+
const startingArrayIndex_fractional = Math.min(Math.max(scrollPercentage * dimensions.pageCount_fractional, 0), dimensions.pageCount_fractional) * dimensions.itemsPerPage;
|
|
893
|
+
const maxStart = dimensions.itemCount - dimensions.itemsPerPage - 1;
|
|
894
|
+
let arrayStartIndex = Math.min(Math.floor(startingArrayIndex_fractional), maxStart);
|
|
895
|
+
arrayStartIndex -= arrayStartIndex % dimensions.itemsPerWrapGroup; // round down to start of wrapGroup
|
|
896
|
+
if (this.stripedTable) {
|
|
897
|
+
const bufferBoundary = 2 * dimensions.itemsPerWrapGroup;
|
|
898
|
+
if (arrayStartIndex % bufferBoundary !== 0) {
|
|
899
|
+
arrayStartIndex = Math.max(arrayStartIndex - arrayStartIndex % bufferBoundary, 0);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
let arrayEndIndex = Math.ceil(startingArrayIndex_fractional) + dimensions.itemsPerPage - 1;
|
|
903
|
+
const endIndexWithinWrapGroup = (arrayEndIndex + 1) % dimensions.itemsPerWrapGroup;
|
|
904
|
+
if (endIndexWithinWrapGroup > 0) {
|
|
905
|
+
arrayEndIndex += dimensions.itemsPerWrapGroup - endIndexWithinWrapGroup; // round up to end of wrapGroup
|
|
906
|
+
}
|
|
907
|
+
if (isNaN(arrayStartIndex)) {
|
|
908
|
+
arrayStartIndex = 0;
|
|
909
|
+
}
|
|
910
|
+
if (isNaN(arrayEndIndex)) {
|
|
911
|
+
arrayEndIndex = 0;
|
|
912
|
+
}
|
|
913
|
+
arrayStartIndex = Math.min(Math.max(arrayStartIndex, 0), dimensions.itemCount - 1);
|
|
914
|
+
arrayEndIndex = Math.min(Math.max(arrayEndIndex, 0), dimensions.itemCount - 1);
|
|
915
|
+
const bufferSize = this.bufferAmount * dimensions.itemsPerWrapGroup;
|
|
916
|
+
const startIndexWithBuffer = Math.min(Math.max(arrayStartIndex - bufferSize, 0), dimensions.itemCount - 1);
|
|
917
|
+
const endIndexWithBuffer = Math.min(Math.max(arrayEndIndex + bufferSize, 0), dimensions.itemCount - 1);
|
|
918
|
+
return {
|
|
919
|
+
startIndex: arrayStartIndex,
|
|
920
|
+
endIndex: arrayEndIndex,
|
|
921
|
+
startIndexWithBuffer: startIndexWithBuffer,
|
|
922
|
+
endIndexWithBuffer: endIndexWithBuffer,
|
|
923
|
+
scrollStartPosition: scrollPosition,
|
|
924
|
+
scrollEndPosition: scrollPosition + dimensions.viewportLength,
|
|
925
|
+
maxScrollPosition: dimensions.maxScrollPosition
|
|
926
|
+
};
|
|
927
|
+
}
|
|
928
|
+
calculateViewport() {
|
|
929
|
+
const dimensions = this.calculateDimensions();
|
|
930
|
+
const offset = this.getElementsOffset();
|
|
931
|
+
let scrollStartPosition = this.getScrollStartPosition();
|
|
932
|
+
if (scrollStartPosition > (dimensions.scrollLength + offset) && !(this.parentScroll instanceof Window)) {
|
|
933
|
+
scrollStartPosition = dimensions.scrollLength;
|
|
934
|
+
}
|
|
935
|
+
else {
|
|
936
|
+
scrollStartPosition -= offset;
|
|
937
|
+
}
|
|
938
|
+
scrollStartPosition = Math.max(0, scrollStartPosition);
|
|
939
|
+
const pageInfo = this.calculatePageInfo(scrollStartPosition, dimensions);
|
|
940
|
+
const newPadding = this.calculatePadding(pageInfo.startIndexWithBuffer, dimensions);
|
|
941
|
+
const newScrollLength = dimensions.scrollLength;
|
|
942
|
+
return {
|
|
943
|
+
startIndex: pageInfo.startIndex,
|
|
944
|
+
endIndex: pageInfo.endIndex,
|
|
945
|
+
startIndexWithBuffer: pageInfo.startIndexWithBuffer,
|
|
946
|
+
endIndexWithBuffer: pageInfo.endIndexWithBuffer,
|
|
947
|
+
padding: Math.round(newPadding),
|
|
948
|
+
scrollLength: Math.round(newScrollLength),
|
|
949
|
+
scrollStartPosition: pageInfo.scrollStartPosition,
|
|
950
|
+
scrollEndPosition: pageInfo.scrollEndPosition,
|
|
951
|
+
maxScrollPosition: pageInfo.maxScrollPosition
|
|
952
|
+
};
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
VirtualScrollerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: VirtualScrollerComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: PLATFORM_ID }, { token: 'virtual-scroller-default-options', optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
956
956
|
VirtualScrollerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.2", type: VirtualScrollerComponent, selector: "virtual-scroller,[virtualScroller]", inputs: { disable: "disable", executeRefreshOutsideAngularZone: "executeRefreshOutsideAngularZone", enableUnequalChildrenSizes: "enableUnequalChildrenSizes", RTL: "RTL", useMarginInsteadOfTranslate: "useMarginInsteadOfTranslate", modifyOverflowStyleOfParentScroll: "modifyOverflowStyleOfParentScroll", stripedTable: "stripedTable", scrollbarWidth: "scrollbarWidth", scrollbarHeight: "scrollbarHeight", childWidth: "childWidth", childHeight: "childHeight", ssrChildWidth: "ssrChildWidth", ssrChildHeight: "ssrChildHeight", ssrViewportWidth: "ssrViewportWidth", ssrViewportHeight: "ssrViewportHeight", bufferAmount: "bufferAmount", scrollAnimationTime: "scrollAnimationTime", resizeBypassRefreshThreshold: "resizeBypassRefreshThreshold", scrollThrottlingTime: "scrollThrottlingTime", scrollDebounceTime: "scrollDebounceTime", checkResizeInterval: "checkResizeInterval", items: "items", compareItems: "compareItems", horizontal: "horizontal", parentScroll: "parentScroll" }, outputs: { vsChildRectChange: "vsChildRectChange", vsUpdate: "vsUpdate", vsChange: "vsChange", vsStart: "vsStart", vsEnd: "vsEnd" }, host: { properties: { "class.horizontal": "horizontal", "class.vertical": "!horizontal", "class.selfScroll": "!parentScroll", "class.rtl": "RTL" } }, queries: [{ propertyName: "headerElementRef", first: true, predicate: ["header"], descendants: true, read: ElementRef }, { propertyName: "containerElementRef", first: true, predicate: ["container"], descendants: true, read: ElementRef }], viewQueries: [{ propertyName: "contentElementRef", first: true, predicate: ["content"], descendants: true, read: ElementRef, static: true }, { propertyName: "invisiblePaddingElementRef", first: true, predicate: ["invisiblePadding"], descendants: true, read: ElementRef, static: true }], exportAs: ["virtualScroller"], usesOnChanges: true, ngImport: i0, template: `
|
|
957
957
|
<div class="total-padding" #invisiblePadding></div>
|
|
958
958
|
<div class="scrollable-content" #content>
|
|
959
959
|
<ng-content></ng-content>
|
|
960
960
|
</div>
|
|
961
|
-
`, isInline: true, styles: [":host{position:relative;display:block;-webkit-overflow-scrolling:touch}:host.horizontal.selfScroll{overflow-y:visible;overflow-x:auto}:host.horizontal.selfScroll.rtl{transform:scaleX(-1)}:host.vertical.selfScroll{overflow-y:auto;overflow-x:visible}.scrollable-content{top:0;left:0;width:100%;height:100%;max-width:100vw;max-height:100vh;position:absolute}.scrollable-content ::ng-deep>*{box-sizing:border-box}:host.horizontal{white-space:nowrap}:host.horizontal .scrollable-content{display:flex}:host.horizontal .scrollable-content ::ng-deep>*{flex-shrink:0;flex-grow:0;white-space:initial}:host.horizontal.rtl .scrollable-content ::ng-deep>*{transform:scaleX(-1)}.total-padding{position:absolute;top:0;left:0;height:1px;width:1px;transform-origin:0 0;opacity:0}:host.horizontal .total-padding{height:100%}\n"] });
|
|
962
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: VirtualScrollerComponent, decorators: [{
|
|
963
|
-
type: Component,
|
|
961
|
+
`, isInline: true, styles: [":host{position:relative;display:block;-webkit-overflow-scrolling:touch}:host.horizontal.selfScroll{overflow-y:visible;overflow-x:auto}:host.horizontal.selfScroll.rtl{transform:scaleX(-1)}:host.vertical.selfScroll{overflow-y:auto;overflow-x:visible}.scrollable-content{top:0;left:0;width:100%;height:100%;max-width:100vw;max-height:100vh;position:absolute}.scrollable-content ::ng-deep>*{box-sizing:border-box}:host.horizontal{white-space:nowrap}:host.horizontal .scrollable-content{display:flex}:host.horizontal .scrollable-content ::ng-deep>*{flex-shrink:0;flex-grow:0;white-space:initial}:host.horizontal.rtl .scrollable-content ::ng-deep>*{transform:scaleX(-1)}.total-padding{position:absolute;top:0;left:0;height:1px;width:1px;transform-origin:0 0;opacity:0}:host.horizontal .total-padding{height:100%}\n"] });
|
|
962
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: VirtualScrollerComponent, decorators: [{
|
|
963
|
+
type: Component,
|
|
964
964
|
args: [{ selector: 'virtual-scroller,[virtualScroller]', exportAs: 'virtualScroller', template: `
|
|
965
965
|
<div class="total-padding" #invisiblePadding></div>
|
|
966
966
|
<div class="scrollable-content" #content>
|
|
967
967
|
<ng-content></ng-content>
|
|
968
968
|
</div>
|
|
969
|
-
`, host: {
|
|
970
|
-
'[class.horizontal]': "horizontal",
|
|
971
|
-
'[class.vertical]': "!horizontal",
|
|
972
|
-
'[class.selfScroll]': "!parentScroll",
|
|
973
|
-
'[class.rtl]': "RTL"
|
|
974
|
-
}, styles: [":host{position:relative;display:block;-webkit-overflow-scrolling:touch}:host.horizontal.selfScroll{overflow-y:visible;overflow-x:auto}:host.horizontal.selfScroll.rtl{transform:scaleX(-1)}:host.vertical.selfScroll{overflow-y:auto;overflow-x:visible}.scrollable-content{top:0;left:0;width:100%;height:100%;max-width:100vw;max-height:100vh;position:absolute}.scrollable-content ::ng-deep>*{box-sizing:border-box}:host.horizontal{white-space:nowrap}:host.horizontal .scrollable-content{display:flex}:host.horizontal .scrollable-content ::ng-deep>*{flex-shrink:0;flex-grow:0;white-space:initial}:host.horizontal.rtl .scrollable-content ::ng-deep>*{transform:scaleX(-1)}.total-padding{position:absolute;top:0;left:0;height:1px;width:1px;transform-origin:0 0;opacity:0}:host.horizontal .total-padding{height:100%}\n"] }]
|
|
975
|
-
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
|
|
976
|
-
type: Inject,
|
|
977
|
-
args: [PLATFORM_ID]
|
|
978
|
-
}] }, { type: undefined, decorators: [{
|
|
979
|
-
type: Optional
|
|
980
|
-
}, {
|
|
981
|
-
type: Inject,
|
|
982
|
-
args: ['virtual-scroller-default-options']
|
|
983
|
-
}] }]; }, propDecorators: { disable: [{
|
|
984
|
-
type: Input
|
|
985
|
-
}], executeRefreshOutsideAngularZone: [{
|
|
986
|
-
type: Input
|
|
987
|
-
}], enableUnequalChildrenSizes: [{
|
|
988
|
-
type: Input
|
|
989
|
-
}], RTL: [{
|
|
990
|
-
type: Input
|
|
991
|
-
}], useMarginInsteadOfTranslate: [{
|
|
992
|
-
type: Input
|
|
993
|
-
}], modifyOverflowStyleOfParentScroll: [{
|
|
994
|
-
type: Input
|
|
995
|
-
}], stripedTable: [{
|
|
996
|
-
type: Input
|
|
997
|
-
}], scrollbarWidth: [{
|
|
998
|
-
type: Input
|
|
999
|
-
}], scrollbarHeight: [{
|
|
1000
|
-
type: Input
|
|
1001
|
-
}], childWidth: [{
|
|
1002
|
-
type: Input
|
|
1003
|
-
}], childHeight: [{
|
|
1004
|
-
type: Input
|
|
1005
|
-
}], ssrChildWidth: [{
|
|
1006
|
-
type: Input
|
|
1007
|
-
}], ssrChildHeight: [{
|
|
1008
|
-
type: Input
|
|
1009
|
-
}], ssrViewportWidth: [{
|
|
1010
|
-
type: Input
|
|
1011
|
-
}], ssrViewportHeight: [{
|
|
1012
|
-
type: Input
|
|
1013
|
-
}], bufferAmount: [{
|
|
1014
|
-
type: Input
|
|
1015
|
-
}], scrollAnimationTime: [{
|
|
1016
|
-
type: Input
|
|
1017
|
-
}], resizeBypassRefreshThreshold: [{
|
|
1018
|
-
type: Input
|
|
1019
|
-
}], scrollThrottlingTime: [{
|
|
1020
|
-
type: Input
|
|
1021
|
-
}], scrollDebounceTime: [{
|
|
1022
|
-
type: Input
|
|
1023
|
-
}], checkResizeInterval: [{
|
|
1024
|
-
type: Input
|
|
1025
|
-
}], items: [{
|
|
1026
|
-
type: Input
|
|
1027
|
-
}], compareItems: [{
|
|
1028
|
-
type: Input
|
|
1029
|
-
}], horizontal: [{
|
|
1030
|
-
type: Input
|
|
1031
|
-
}], parentScroll: [{
|
|
1032
|
-
type: Input
|
|
1033
|
-
}], vsChildRectChange: [{
|
|
1034
|
-
type: Output
|
|
1035
|
-
}], vsUpdate: [{
|
|
1036
|
-
type: Output
|
|
1037
|
-
}], vsChange: [{
|
|
1038
|
-
type: Output
|
|
1039
|
-
}], vsStart: [{
|
|
1040
|
-
type: Output
|
|
1041
|
-
}], vsEnd: [{
|
|
1042
|
-
type: Output
|
|
1043
|
-
}], contentElementRef: [{
|
|
1044
|
-
type: ViewChild,
|
|
1045
|
-
args: ['content', { read: ElementRef, static: true }]
|
|
1046
|
-
}], invisiblePaddingElementRef: [{
|
|
1047
|
-
type: ViewChild,
|
|
1048
|
-
args: ['invisiblePadding', { read: ElementRef, static: true }]
|
|
1049
|
-
}], headerElementRef: [{
|
|
1050
|
-
type: ContentChild,
|
|
1051
|
-
args: ['header', { read: ElementRef, static: false }]
|
|
1052
|
-
}], containerElementRef: [{
|
|
1053
|
-
type: ContentChild,
|
|
1054
|
-
args: ['container', { read: ElementRef, static: false }]
|
|
1055
|
-
}] } });
|
|
1056
|
-
export class VirtualScrollerModule {
|
|
1057
|
-
}
|
|
1058
|
-
VirtualScrollerModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: VirtualScrollerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
1059
|
-
VirtualScrollerModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.0.2", ngImport: i0, type: VirtualScrollerModule, declarations: [VirtualScrollerComponent], imports: [CommonModule], exports: [VirtualScrollerComponent] });
|
|
1060
|
-
VirtualScrollerModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: VirtualScrollerModule, providers: [
|
|
1061
|
-
{
|
|
1062
|
-
provide: 'virtual-scroller-default-options',
|
|
1063
|
-
useFactory: VIRTUAL_SCROLLER_DEFAULT_OPTIONS_FACTORY
|
|
1064
|
-
}
|
|
1065
|
-
], imports: [CommonModule] });
|
|
1066
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: VirtualScrollerModule, decorators: [{
|
|
1067
|
-
type: NgModule,
|
|
1068
|
-
args: [{
|
|
1069
|
-
exports: [VirtualScrollerComponent],
|
|
1070
|
-
declarations: [VirtualScrollerComponent],
|
|
1071
|
-
imports: [CommonModule],
|
|
1072
|
-
providers: [
|
|
1073
|
-
{
|
|
1074
|
-
provide: 'virtual-scroller-default-options',
|
|
1075
|
-
useFactory: VIRTUAL_SCROLLER_DEFAULT_OPTIONS_FACTORY
|
|
1076
|
-
}
|
|
1077
|
-
]
|
|
1078
|
-
}]
|
|
1079
|
-
}] });
|
|
1080
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlydHVhbC1zY3JvbGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1saWIvbGlzdC92aXJ0dWFsLXNjcm9sbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFTixTQUFTLEVBQ1QsWUFBWSxFQUNaLFVBQVUsRUFDVixZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFDTCxRQUFRLEVBS1IsUUFBUSxFQUNSLE1BQU0sRUFFTixTQUFTLEdBQ1QsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM1QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUVuRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFL0MsT0FBTyxLQUFLLEtBQUssTUFBTSxtQkFBbUIsQ0FBQTs7QUFjMUMsTUFBTSxVQUFVLHdDQUF3QztJQUN2RCxPQUFPO1FBQ04sbUJBQW1CLEVBQUUsSUFBSTtRQUN6QixpQ0FBaUMsRUFBRSxJQUFJO1FBQ3ZDLDRCQUE0QixFQUFFLENBQUM7UUFDL0IsbUJBQW1CLEVBQUUsR0FBRztRQUN4QixrQkFBa0IsRUFBRSxDQUFDO1FBQ3JCLG9CQUFvQixFQUFFLENBQUM7UUFDdkIsWUFBWSxFQUFFLEtBQUs7S0FDbkIsQ0FBQztBQUNILENBQUM7QUFzSEQsTUFBTSxPQUFPLHdCQUF3QjtJQThicEMsWUFDb0IsT0FBbUIsRUFDbkIsUUFBbUIsRUFDbkIsSUFBWSxFQUNyQixpQkFBb0MsRUFDekIsVUFBZSxFQUVwQyxPQUFzQztRQU5uQixZQUFPLEdBQVAsT0FBTyxDQUFZO1FBQ25CLGFBQVEsR0FBUixRQUFRLENBQVc7UUFDbkIsU0FBSSxHQUFKLElBQUksQ0FBUTtRQUNyQixzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBaGN4QyxXQUFNLEdBQUcsTUFBTSxDQUFDO1FB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QUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFOztBQXU4Qi9ELE1BQU0sT0FBTyxxQkFBcUI7O2tIQUFyQixxQkFBcUI7bUhBQXJCLHFCQUFxQixpQkFoc0NyQix3QkFBd0IsYUF3ckMxQixZQUFZLGFBeHJDVix3QkFBd0I7bUhBZ3NDeEIscUJBQXFCLGFBUHRCO1FBQ1Y7WUFDQyxPQUFPLEVBQUUsa0NBQWtDO1lBQzNDLFVBQVUsRUFBRSx3Q0FBd0M7U0FDcEQ7S0FDRCxZQU5TLFlBQVk7MkZBUVYscUJBQXFCO2tCQVhqQyxRQUFRO21CQUFDO29CQUNULE9BQU8sRUFBRSxDQUFDLHdCQUF3QixDQUFDO29CQUNuQyxZQUFZLEVBQUUsQ0FBQyx3QkFBd0IsQ0FBQztvQkFDeEMsT0FBTyxFQUFFLENBQUMsWUFBWSxDQUFDO29CQUN2QixTQUFTLEVBQUU7d0JBQ1Y7NEJBQ0MsT0FBTyxFQUFFLGtDQUFrQzs0QkFDM0MsVUFBVSxFQUFFLHdDQUF3Qzt5QkFDcEQ7cUJBQ0Q7aUJBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG5cdENoYW5nZURldGVjdG9yUmVmLFxyXG5cdENvbXBvbmVudCxcclxuXHRDb250ZW50Q2hpbGQsXHJcblx0RWxlbWVudFJlZixcclxuXHRFdmVudEVtaXR0ZXIsXHJcblx0SW5qZWN0LFxyXG5cdElucHV0LFxyXG5cdE5nTW9kdWxlLFxyXG5cdE5nWm9uZSxcclxuXHRPbkNoYW5nZXMsXHJcblx0T25EZXN0cm95LFxyXG5cdE9uSW5pdCxcclxuXHRPcHRpb25hbCxcclxuXHRPdXRwdXQsXHJcblx0UmVuZGVyZXIyLFxyXG5cdFZpZXdDaGlsZCxcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuXHJcbmltcG9ydCB7IFBMQVRGT1JNX0lEIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IGlzUGxhdGZvcm1TZXJ2ZXIgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5cclxuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuXHJcbmltcG9ydCAqIGFzIHR3ZWVuIGZyb20gJ0B0d2VlbmpzL3R3ZWVuLmpzJ1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBWaXJ0dWFsU2Nyb2xsZXJEZWZhdWx0T3B0aW9ucyB7XHJcblx0Y2hlY2tSZXNpemVJbnRlcnZhbDogbnVtYmVyXHJcblx0bW9kaWZ5T3ZlcmZsb3dTdHlsZU9mUGFyZW50U2Nyb2xsOiBib29sZWFuLFxyXG5cdHJlc2l6ZUJ5cGFzc1JlZnJlc2hUaHJlc2hvbGQ6IG51bWJlcixcclxuXHRzY3JvbGxBbmltYXRpb25UaW1lOiBudW1iZXI7XHJcblx0c2Nyb2xsRGVib3VuY2VUaW1lOiBudW1iZXI7XHJcblx0c2Nyb2xsVGhyb3R0bGluZ1RpbWU6IG51bWJlcjtcclxuXHRzY3JvbGxiYXJIZWlnaHQ/OiBudW1iZXI7XHJcblx0c2Nyb2xsYmFyV2lkdGg/OiBudW1iZXI7XHJcblx0c3RyaXBlZFRhYmxlOiBib29sZWFuXHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBWSVJUVUFMX1NDUk9MTEVSX0RFRkFVTFRfT1BUSU9OU19GQUNUT1JZKCk6IFZpcnR1YWxTY3JvbGxlckRlZmF1bHRPcHRpb25zIHtcclxuXHRyZXR1cm4ge1xyXG5cdFx0Y2hlY2tSZXNpemVJbnRlcnZhbDogMTAwMCxcclxuXHRcdG1vZGlmeU92ZXJmbG93U3R5bGVPZlBhcmVudFNjcm9sbDogdHJ1ZSxcclxuXHRcdHJlc2l6ZUJ5cGFzc1JlZnJlc2hUaHJlc2hvbGQ6IDUsXHJcblx0XHRzY3JvbGxBbmltYXRpb25UaW1lOiA3NTAsXHJcblx0XHRzY3JvbGxEZWJvdW5jZVRpbWU6IDAsXHJcblx0XHRzY3JvbGxUaHJvdHRsaW5nVGltZTogMCxcclxuXHRcdHN0cmlwZWRUYWJsZTogZmFsc2VcclxuXHR9O1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFdyYXBHcm91cERpbWVuc2lvbnMge1xyXG5cdG1heENoaWxkU2l6ZVBlcldyYXBHcm91cDogV3JhcEdyb3VwRGltZW5zaW9uW107XHJcblx0bnVtYmVyT2ZLbm93bldyYXBHcm91cENoaWxkU2l6ZXM6IG51bWJlcjtcclxuXHRzdW1PZktub3duV3JhcEdyb3VwQ2hpbGRIZWlnaHRzOiBudW1iZXI7XHJcblx0c3VtT2ZLbm93bldyYXBHcm91cENoaWxkV2lkdGhzOiBudW1iZXI7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgV3JhcEdyb3VwRGltZW5zaW9uIHtcclxuXHRjaGlsZEhlaWdodDogbnVtYmVyO1xyXG5cdGNoaWxkV2lkdGg6IG51bWJlcjtcclxuXHRpdGVtczogYW55W107XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgSURpbWVuc2lvbnMge1xyXG5cdGNoaWxkSGVpZ2h0OiBudW1iZXI7XHJcblx0Y2hpbGRXaWR0aDogbnVtYmVyO1xyXG5cdGl0ZW1Db3VudDogbnVtYmVyO1xyXG5cdGl0ZW1zUGVyUGFnZTogbnVtYmVyO1xyXG5cdGl0ZW1zUGVyV3JhcEdyb3VwOiBudW1iZXI7XHJcblx0bWF4U2Nyb2xsUG9zaXRpb246IG51bWJlcjtcclxuXHRwYWdlQ291bnRfZnJhY3Rpb25hbDogbnVtYmVyO1xyXG5cdHNjcm9sbExlbmd0aDogbnVtYmVyO1xyXG5cdHZpZXdwb3J0TGVuZ3RoOiBudW1iZXI7XHJcblx0d3JhcEdyb3Vwc1BlclBhZ2U6IG51bWJlcjtcclxufVxyXG5cclxuZXhwb3J0IHR5cGUgU2Nyb2xsRGlyZWN0aW9uVHlwZSA9ICdiYWNrd2FyZCcgfCAnZm9yd2FyZCc7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIElQYWdlSW5mbyB7XHJcblx0ZW5kSW5kZXg6IG51bWJlcjtcclxuXHRlbmRJbmRleFdpdGhCdWZmZXI6IG51bWJlcjtcclxuXHRtYXhTY3JvbGxQb3NpdGlvbjogbnVtYmVyO1xyXG5cdHNjcm9sbEVuZFBvc2l0aW9uOiBudW1iZXI7XHJcblx0c2Nyb2xsU3RhcnRQb3NpdGlvbjogbnVtYmVyO1xyXG5cdHNjcm9sbERpcmVjdGlvbj86IFNjcm9sbERpcmVjdGlvblR5cGU7XHJcblx0c3RhcnRJbmRleDogbnVtYmVyO1xyXG5cdHN0YXJ0SW5kZXhXaXRoQnVmZmVyOiBudW1iZXI7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgSVZpZXdwb3J0IGV4dGVuZHMgSVBhZ2VJbmZvIHtcclxuXHRwYWRkaW5nOiBudW1iZXI7XHJcblx0c2Nyb2xsTGVuZ3RoOiBudW1iZXI7XHJcbn1cclxuXHJcbkBDb21wb25lbnQoe1xyXG5cdHNlbGVjdG9yOiAndmlydHVhbC1zY3JvbGxlcixbdmlydHVhbFNjcm9sbGVyXScsXHJcblx0ZXhwb3J0QXM6ICd2aXJ0dWFsU2Nyb2xsZXInLFxyXG5cdHRlbXBsYXRlOiBgXHJcbiAgICA8ZGl2IGNsYXNzPVwidG90YWwtcGFkZGluZ1wiICNpbnZpc2libGVQYWRkaW5nPjwvZGl2PlxyXG4gICAgPGRpdiBjbGFzcz1cInNjcm9sbGFibGUtY29udGVudFwiICNjb250ZW50PlxyXG4gICAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XHJcbiAgICA8L2Rpdj5cclxuICBgLFxyXG5cdGhvc3Q6IHtcclxuXHRcdCdbY2xhc3MuaG9yaXpvbnRhbF0nOiBcImhvcml6b250YWxcIixcclxuXHRcdCdbY2xhc3MudmVydGljYWxdJzogXCIhaG9yaXpvbnRhbFwiLFxyXG5cdFx0J1tjbGFzcy5zZWxmU2Nyb2xsXSc6IFwiIXBhcmVudFNjcm9sbFwiLFxyXG5cdFx0J1tjbGFzcy5ydGxdJzogXCJSVExcIlxyXG5cdH0sXHJcblx0c3R5bGVzOiBbYFxyXG4gICAgOmhvc3Qge1xyXG4gICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XHJcblx0ICBcdGRpc3BsYXk6IGJsb2NrO1xyXG4gICAgICAtd2Via2l0LW92ZXJmbG93LXNjcm9sbGluZzogdG91Y2g7XHJcbiAgICB9XHJcblx0XHQ6aG9zdC5ob3Jpem9udGFsLnNlbGZTY3JvbGwge1xyXG4gICAgICBvdmVyZmxvdy15OiB2aXNpYmxlO1xyXG4gICAgICBvdmVyZmxvdy14OiBhdXRvO1xyXG5cdFx0fVxyXG5cdFx0Omhvc3QuaG9yaXpvbnRhbC5zZWxmU2Nyb2xsLnJ0bCB7XHJcblx0XHRcdHRyYW5zZm9ybTogc2NhbGVYKC0xKTtcclxuXHRcdH1cclxuXHRcdDpob3N0LnZlcnRpY2FsLnNlbGZTY3JvbGwge1xyXG4gICAgICBvdmVyZmxvdy15OiBhdXRvO1xyXG4gICAgICBvdmVyZmxvdy14OiB2aXNpYmxlO1xyXG5cdFx0fVxyXG4gICAgLnNjcm9sbGFibGUtY29udGVudCB7XHJcbiAgICAgIHRvcDogMDtcclxuICAgICAgbGVmdDogMDtcclxuICAgICAgd2lkdGg6IDEwMCU7XHJcbiAgICAgIGhlaWdodDogMTAwJTtcclxuICAgICAgbWF4LXdpZHRoOiAxMDB2dztcclxuICAgICAgbWF4LWhlaWdodDogMTAwdmg7XHJcbiAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcclxuICAgIH1cclxuXHRcdC5zY3JvbGxhYmxlLWNvbnRlbnQgOjpuZy1kZWVwID4gKiB7XHJcblx0XHRcdGJveC1zaXppbmc6IGJvcmRlci1ib3g7XHJcblx0XHR9XHJcblx0XHQ6aG9zdC5ob3Jpem9udGFsIHtcclxuXHRcdFx0d2hpdGUtc3BhY2U6IG5vd3JhcDtcclxuXHRcdH1cclxuXHRcdDpob3N0Lmhvcml6b250YWwgLnNjcm9sbGFibGUtY29udGVudCB7XHJcblx0XHRcdGRpc3BsYXk6IGZsZXg7XHJcblx0XHR9XHJcblx0XHQ6aG9zdC5ob3Jpem9udGFsIC5zY3JvbGxhYmxlLWNvbnRlbnQgOjpuZy1kZWVwID4gKiB7XHJcblx0XHRcdGZsZXgtc2hyaW5rOiAwO1xyXG5cdFx0XHRmbGV4LWdyb3c6IDA7XHJcblx0XHRcdHdoaXRlLXNwYWNlOiBpbml0aWFsO1xyXG5cdFx0fVxyXG5cdFx0Omhvc3QuaG9yaXpvbnRhbC5ydGwgLnNjcm9sbGFibGUtY29udGVudCA6Om5nLWRlZXAgPiAqIHtcclxuXHRcdFx0dHJhbnNmb3JtOnNjYWxlWCgtMSk7XHJcblx0XHR9XHJcbiAgICAudG90YWwtcGFkZGluZyB7XHJcbiAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcclxuICAgICAgdG9wOiAwO1xyXG4gICAgICBsZWZ0OiAwO1xyXG4gICAgICBoZWlnaHQ6IDFweDtcclxuICAgICAgd2lkdGg6IDFweDtcclxuICAgICAgdHJhbnNmb3JtLW9yaWdpbjogMCAwO1xyXG4gICAgICBvcGFjaXR5OiAwO1xyXG4gICAgfVxyXG4gICAgOmhvc3QuaG9yaXpvbnRhbCAudG90YWwtcGFkZGluZyB7XHJcbiAgICAgIGhlaWdodDogMTAwJTtcclxuICAgIH1cclxuICBgXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgVmlydHVhbFNjcm9sbGVyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XHJcblx0cHVibGljIHZpZXdQb3J0SXRlbXM6IGFueVtdO1xyXG5cdHB1YmxpYyB3aW5kb3cgPSB3aW5kb3c7XHJcblxyXG5cdHB1YmxpYyBnZXQgdmlld1BvcnRJbmZvKCk6IElQYWdlSW5mbyB7XHJcblx0XHRjb25zdCBwYWdlSW5mbzogSVZpZXdwb3J0ID0gdGhpcy5wcmV2aW91c1ZpZXdQb3J0IHx8IDxhbnk+e307XHJcblx0XHRyZXR1cm4ge1xyXG5cdFx0XHRzdGFydEluZGV4OiBwYWdlSW5mby5zdGFydEluZGV4IHx8IDAsXHJcblx0XHRcdGVuZEluZGV4OiBwYWdlSW5mby5lbmRJbmRleCB8fCAwLFxyXG5cdFx0XHRzY3JvbGxTdGFydFBvc2l0aW9uOiBwYWdlSW5mby5zY3JvbGxTdGFydFBvc2l0aW9uIHx8IDAsXHJcblx0XHRcdHNjcm9sbEVuZFBvc2l0aW9uOiBwYWdlSW5mby5zY3JvbGxFbmRQb3NpdGlvbiB8fCAwLFxyXG5cdFx0XHRzY3JvbGxEaXJlY3Rpb246IHBhZ2VJbmZvLnNjcm9sbERpcmVjdGlvbiB8fCAnZm9yd2FyZCcsXHJcblx0XHRcdG1heFNjcm9sbFBvc2l0aW9uOiBwYWdlSW5mby5tYXhTY3JvbGxQb3NpdGlvbiB8fCAwLFxyXG5cdFx0XHRzdGFydEluZGV4V2l0aEJ1ZmZlcjogcGFnZUluZm8uc3RhcnRJbmRleFdpdGhCdWZmZXIgfHwgMCxcclxuXHRcdFx0ZW5kSW5kZXhXaXRoQnVmZmVyOiBwYWdlSW5mby5lbmRJbmRleFdpdGhCdWZmZXIgfHwgMCxcclxuXHRcdH07XHJcblx0fVxyXG5cclxuXHRwcm90ZWN0ZWQgX2Rpc2FibGUgPSBmYWxzZTtcclxuXHRASW5wdXQoKVxyXG5cdHB1YmxpYyBnZXQgZGlzYWJsZSgpOiBib29sZWFuIHtcclxuXHRcdHJldHVybiB0aGlzLl9kaXNhYmxlO1xyXG5cdH1cclxuXHRwdWJsaWMgc2V0IGRpc2FibGUodmFsdWU6IGJvb2xlYW4pIHtcclxuXHRcdGlmICh0aGlzLl9kaXNhYmxlID09PSB2YWx1ZSkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0dGhpcy5fZGlzYWJsZSA9IHZhbHVlO1xyXG5cdFx0aWYgKHRoaXMuX2Rpc2FibGUpIHtcclxuXHRcdFx0dGhpcy5yZW1vdmVTY3JvbGxFdmVudEhhbmRsZXJzKCk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHR0aGlzLmFkZFNjcm9sbEV2ZW50SGFuZGxlcnMoKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdEBJbnB1dCgpXHJcblx0cHVibGljIGV4ZWN1dGVSZWZyZXNoT3V0c2lkZUFuZ3VsYXJab25lID0gZmFsc2U7XHJcblxyXG5cdHByb3RlY3RlZCBfZW5hYmxlVW5lcXVhbENoaWxkcmVuU2l6ZXMgPSBmYWxzZTtcclxuXHRASW5wdXQoKVxyXG5cdHB1YmxpYyBnZXQgZW5hYmxlVW5lcXVhbENoaWxkcmVuU2l6ZXMoKTogYm9vbGVhbiB7XHJcblx0XHRyZXR1cm4gdGhpcy5fZW5hYmxlVW5lcXVhbENoaWxkcmVuU2l6ZXM7XHJcblx0fVxyXG5cdHB1YmxpYyBzZXQgZW5hYmxlVW5lcXVhbENoaWxkcmVuU2l6ZXModmFsdWU6IGJvb2xlYW4pIHtcclxuXHRcdGlmICh0aGlzLl9lbmFibGVVbmVxdWFsQ2hpbGRyZW5TaXplcyA9PT0gdmFsdWUpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdHRoaXMuX2VuYWJsZVVuZXF1YWxDaGlsZHJlblNpemVzID0gdmFsdWU7XHJcblx0XHR0aGlzLm1pbk1lYXN1cmVkQ2hpbGRXaWR0aCA9IHVuZGVmaW5lZDtcclxuXHRcdHRoaXMubWluTWVhc3VyZWRDaGlsZEhlaWdodCA9IHVuZGVmaW5lZDtcclxuXHR9XHJcblxyXG5cdEBJbnB1dCgpXHJcblx0cHVibGljIFJUTCA9IGZhbHNlO1xyXG5cclxuXHRASW5wdXQoKVxyXG5cdHB1YmxpYyB1c2VNYXJnaW5JbnN0ZWFkT2ZUcmFuc2xhdGUgPSBmYWxzZTtcclxuXHJcblx0QElucHV0KClcclxuXHRwdWJsaWMgbW9kaWZ5T3ZlcmZsb3dTdHlsZU9mUGFyZW50U2Nyb2xsOiBib29sZWFuO1xyXG5cclxuXHRASW5wdXQoKVxyXG5cdHB1YmxpYyBzdHJpcGVkVGFibGU6IGJvb2xlYW47XHJcblxyXG5cdEBJbnB1dCgpXHJcblx0cHVibGljIHNjcm9sbGJhcldpZHRoOiBudW1iZXI7XHJcblxyXG5cdEBJbnB1dCgpXHJcblx0cHVibGljIHNjcm9sbGJhckhlaWdodDogbnVtYmVyO1xyXG5cclxuXHRASW5wdXQoKVxyXG5cdHB1YmxpYyBjaGlsZFdpZHRoOiBudW1iZXI7XHJcblxyXG5cdEBJbnB1dCgpXHJcblx0cHVibGljIGNoaWxkSGVpZ2h0OiBudW1iZXI7XHJcblxyXG5cdEBJbnB1dCgpXHJcblx0cHVibGljIHNzckNoaWxkV2lkdGg6IG51bWJlcjtcclxuXHJcblx0QElucHV0KClcclxuXHRwdWJsaWMgc3NyQ2hpbGRIZWlnaHQ6IG51bWJlcjtcclxuXHJcblx0QElucHV0KClcclxuXHRwdWJsaWMgc3NyVmlld3BvcnRXaWR0aCA9IDE5MjA7XHJcblxyXG5cdEBJbnB1dCgpXHJcblx0cHVibGljIHNzclZpZXdwb3J0SGVpZ2h0ID0gMTA4MDtcclxuXHJcblx0cHJvdGVjdGVkIF9idWZmZXJBbW91bnQ6IG51bWJlcjtcclxuXHRASW5wdXQoKVxyXG5cdHB1YmxpYyBnZXQgYnVmZmVyQW1vdW50KCk6IG51bWJlciB7XHJcblx0XHRpZiAodHlwZW9mICh0aGlzLl9idWZmZXJBbW91bnQpID09PSAnbnVtYmVyJyAmJiB0aGlzLl9idWZmZXJBbW91bnQgPiAwKSB7XHJcblx0XHRcdHJldHVybiB0aGlzLl9idWZmZXJBbW91bnQ7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRyZXR1cm4gdGhpcy5lbmFibGVVbmVxdWFsQ2hpbGRyZW5TaXplcyA/IDUgOiAwO1xyXG5cdFx0fVxyXG5cdH1cclxuXHRwdWJsaWMgc2V0IGJ1ZmZlckFtb3VudCh2YWx1ZTogbnVtYmVyKSB7XHJcblx0XHR0aGlzLl9idWZmZXJBbW91bnQgPSB2YWx1ZTtcclxuXHR9XHJcblxyXG5cdEBJbnB1dCgpXHJcblx0cHVibGljIHNjcm9sbEFuaW1hdGlvblRpbWU6IG51bWJlcjtcclxuXHJcblx0QElucHV0KClcclxuXHRwdWJsaWMgcmVzaXplQnlwYXNzUmVmcmVzaFRocmVzaG9sZDogbnVtYmVyO1xyXG5cclxuXHRwcm90ZWN0ZWQgX3Njcm9sbFRocm90dGxpbmdUaW1lOiBudW1iZXI7XHJcblx0QElucHV0KClcclxuXHRwdWJsaWMgZ2V0IHNjcm9sbFRocm90dGxpbmdUaW1lKCk6IG51bWJlciB7XHJcblx0XHRyZXR1cm4gdGhpcy5fc2Nyb2xsVGhyb3R0bGluZ1RpbWU7XHJcblx0fVxyXG5cdHB1YmxpYyBzZXQgc2Nyb2xsVGhyb3R0bGluZ1RpbWUodmFsdWU6IG51bWJlcikge1xyXG5cdFx0dGhpcy5fc2Nyb2xsVGhyb3R0bGluZ1RpbWUgPSB2YWx1ZTtcclxuXHRcdHRoaXMudXBkYXRlT25TY3JvbGxGdW5jdGlvbigpO1xyXG5cdH1cclxuXHJcblx0cHJvdGVjdGVkIF9zY3JvbGxEZWJvdW5jZVRpbWU6IG51bWJlcjtcclxuXHRASW5wdXQoKVxyXG5cdHB1YmxpYyBnZXQgc2Nyb2xsRGVib3VuY2VUaW1lKCk6IG51bWJlciB7XHJcblx0XHRyZXR1cm4gdGhpcy5fc2Nyb2xsRGVib3VuY2VUaW1lO1xyXG5cdH1cclxuXHRwdWJsaWMgc2V0IHNjcm9sbERlYm91bmNlVGltZSh2YWx1ZTogbnVtYmVyKSB7XHJcblx0XHR0aGlzLl9zY3JvbGxEZWJvdW5jZVRpbWUgPSB2YWx1ZTtcclxuXHRcdHRoaXMudXBkYXRlT25TY3JvbGxGdW5jdGlvbigpO1xyXG5cdH1cclxuXHJcblx0cHJvdGVjdGVkIG9uU2Nyb2xsOiAoKSA9PiB2b2lkO1xyXG5cdHByb3RlY3RlZCB1cGRhdGVPblNjcm9sbEZ1bmN0aW9uKCk6IHZvaWQge1xyXG5cdFx0aWYgKHRoaXMuc2Nyb2xsRGVib3VuY2VUaW1lKSB7XHJcblx0XHRcdHRoaXMub25TY3JvbGwgPSA8YW55PnRoaXMuZGVib3VuY2UoKCkgPT4ge1xyXG5cdFx0XHRcdHRoaXMucmVmcmVzaF9pbnRlcm5hbChmYWxzZSk7XHJcblx0XHRcdH0sIHRoaXMuc2Nyb2xsRGVib3VuY2VUaW1lKTtcclxuXHRcdH1cclxuXHRcdGVsc2UgaWYgKHRoaXMuc2Nyb2xsVGhyb3R0bGluZ1RpbWUpIHtcclxuXHRcdFx0dGhpcy5vblNjcm9sbCA9IDxhbnk+dGhpcy50aHJvdHRsZVRyYWlsaW5nKCgpID0+IHtcclxuXHRcdFx0XHR0aGlzLnJlZnJlc2hfaW50ZXJuYWwoZmFsc2UpO1xyXG5cdFx0XHR9LCB0aGlzLnNjcm9sbFRocm90dGxpbmdUaW1lKTtcclxuXHRcdH1cclxuXHRcdGVsc2Uge1xyXG5cdFx0XHR0aGlzLm9uU2Nyb2xsID0gKCkgPT4ge1xyXG5cdFx0XHRcdHRoaXMucmVmcmVzaF9pbnRlcm5hbChmYWxzZSk7XHJcblx0XHRcdH07XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRwcm90ZWN0ZWQgY2hlY2tTY3JvbGxFbGVtZW50UmVzaXplZFRpbWVyOiBudW1iZXI7XHJcblx0cHJvdGVjdGVkIF9jaGVja1Jlc2l6ZUludGVydmFsOiBudW1iZXI7XHJcblx0QElucHV0KClcclxuXHRwdWJsaWMgZ2V0IGNoZWNrUmVzaXplSW50ZXJ2YWwoKTogbnVtYmVyIHtcclxuXHRcdHJldHVybiB0aGlzLl9jaGVja1Jlc2l6ZUludGVydmFsO1xyXG5cdH1cclxuXHRwdWJsaWMgc2V0IGNoZWNrUmVzaXplSW50ZXJ2YWwodmFsdWU6IG51bWJlcikge1xyXG5cdFx0aWYgKHRoaXMuX2NoZWNrUmVzaXplSW50ZXJ2YWwgPT09IHZhbHVlKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHR0aGlzLl9jaGVja1Jlc2l6ZUludGVydmFsID0gdmFsdWU7XHJcblx0XHR0aGlzLmFkZFNjcm9sbEV2ZW50SGFuZGxlcnMoKTtcclxuXHR9XHJcblxyXG5cdHByb3RlY3RlZCBfaXRlbXM6IGFueVtdID0gW107XHJcblx0QElucHV0KClcclxuXHRwdWJsaWMgZ2V0IGl0ZW1zKCk6IGFueVtdIHtcclxuXHRcdHJldHVybiB0aGlzLl9pdGVtcztcclxuXHR9XHJcblx0cHVibGljIHNldCBpdGVtcyh2YWx1ZTogYW55W10pIHtcclxuXHRcdGlmICh2YWx1ZSA9PT0gdGhpcy5faXRlbXMpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdHRoaXMuX2l0ZW1zID0gdmFsdWUgfHwgW107XHJcblx0XHR0aGlzLnJlZnJlc2hfaW50ZXJuYWwodHJ1ZSk7XHJcblx0fVxyXG5cclxuXHRASW5wdXQoKVxyXG5cdHB1YmxpYyBjb21wYXJlSXRlbXM6IChpdGVtMTogYW55LCBpdGVtMjogYW55KSA9PiBib29sZWFuID0gKGl0ZW0xOiBhbnksIGl0ZW0yOiBhbnkpID0+IGl0ZW0xID09PSBpdGVtMjtcclxuXHJcblx0cHJvdGVjdGVkIF9ob3Jpem9udGFsOiBib29sZWFuO1xyXG5cdEBJbnB1dCgpXHJcblx0cHVibGljIGdldCBob3Jpem9udGFsKCk6IGJvb2xlYW4ge1xyXG5cdFx0cmV0dXJuIHRoaXMuX2hvcml6b250YWw7XHJcblx0fVxyXG5cdHB1YmxpYyBzZXQgaG9yaXpvbnRhbCh2YWx1ZTogYm9vbGVhbikge1xyXG5cdFx0dGhpcy5faG9yaXpvbnRhbCA9IHZhbHVlO1xyXG5cdFx0dGhpcy51cGRhdGVEaXJlY3Rpb24oKTtcclxuXHR9XHJcblxyXG5cdHByb3RlY3RlZCByZXZlcnRQYXJlbnRPdmVyc2Nyb2xsKCk6IHZvaWQge1xyXG5cdFx0Y29uc3Qgc2Nyb2xsRWxlbWVudCA9IHRoaXMuZ2V0U2Nyb2xsRWxlbWVudCgpO1xyXG5cdFx0aWYgKHNjcm9sbEVsZW1lbnQgJiYgdGhpcy5vbGRQYXJlbnRTY3JvbGxPdmVyZmxvdykge1xyXG5cdFx0XHRzY3JvbGxFbGVtZW50LnN0eWxlWydvdmVyZmxvdy15J10gPSB0aGlzLm9sZFBhcmVudFNjcm9sbE92ZXJmbG93Lnk7XHJcblx0XHRcdHNjcm9sbEVsZW1lbnQuc3R5bGVbJ292ZXJmbG93LXgnXSA9IHRoaXMub2xkUGFyZW50U2Nyb2xsT3ZlcmZsb3cueDtcclxuXHRcdH1cclxuXHJcblx0XHR0aGlzLm9sZFBhcmVudFNjcm9sbE92ZXJmbG93ID0gdW5kZWZpbmVkO1xyXG5cdH1cclxuXHJcblx0cHJvdGVjdGVkIG9sZFBhcmVudFNjcm9sbE92ZXJmbG93OiB7IHg6IHN0cmluZywgeTogc3RyaW5nIH07XHJcblx0cHJvdGVjdGVkIF9wYXJlbnRTY3JvbGw6IEVsZW1lbnQgfCBXaW5kb3c7XHJcblx0QElucHV0KClcclxuXHRwdWJsaWMgZ2V0IHBhcmVudFNjcm9sbCgpOiBFbGVtZW50IHwgV2luZG93IHtcclxuXHRcdHJldHVybiB0aGlzLl9wYXJlbnRTY3JvbGw7XHJcblx0fVxyXG5cdHB1YmxpYyBzZXQgcGFyZW50U2Nyb2xsKHZhbHVlOiBFbGVtZW50IHwgV2luZG93KSB7XHJcblx0XHRpZiAodGhpcy5fcGFyZW50U2Nyb2xsID09PSB2YWx1ZSkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0dGhpcy5yZXZlcnRQYXJlbnRPdmVyc2Nyb2xsKCk7XHJcblx0XHR0aGlzLl9wYXJlbnRTY3JvbGwgPSB2YWx1ZTtcclxuXHRcdHRoaXMuYWRkU2Nyb2xsRXZlbnRIYW5kbGVycygpO1xyXG5cclxuXHRcdGNvbnN0IHNjcm9sbEVsZW1lbnQgPSB0aGlzLmdldFNjcm9sbEVsZW1lbnQoKTtcclxuXHRcdGlmICh0aGlzLm1vZGlmeU92ZXJmbG93U3R5bGVPZlBhcmVudFNjcm9sbCAmJiBzY3JvbGxFbGVtZW50ICE9PSB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudCkge1xyXG5cdFx0XHR0aGlzLm9sZFBhcmVudFNjcm9sbE92ZXJmbG93ID0geyB4OiBzY3JvbGxFbGVtZW50LnN0eWxlWydvdmVyZmxvdy14J10sIHk6IHNjcm9sbEVsZW1lbnQuc3R5bGVbJ292ZXJmbG93LXknXSB9O1xyXG5cdFx0XHRzY3JvbGxFbGVtZW50LnN0eWxlWydvdmVyZmxvdy15J10gPSB0aGlzLmhvcml6b250YWwgPyAndmlzaWJsZScgOiAnYXV0byc7XHJcblx0XHRcdHNjcm9sbEVsZW1lbnQuc3R5bGVbJ292ZXJmbG93LXgnXSA9IHRoaXMuaG9yaXpvbnRhbCA/ICdhdXRvJyA6ICd2aXNpYmxlJztcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdC8vIHByaXZhdGUgX2xhc3RDaGlsZFJlY3Q6IERPTVJlY3QgPSBudWxsO1xyXG5cclxuXHRAT3V0cHV0KClcclxuXHRwdWJsaWMgdnNDaGlsZFJlY3RDaGFuZ2U6IEV2ZW50RW1pdHRlcjxET01SZWN0PiA9IG5ldyBFdmVudEVtaXR0ZXI8RE9NUmVjdD4oKTtcclxuXHJcblx0QE91dHB1dCgpXHJcblx0cHVibGljIHZzVXBkYXRlOiBFdmVudEVtaXR0ZXI8YW55W10+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnlbXT4oKTtcclxuXHJcblx0QE91dHB1dCgpXHJcblx0cHVibGljIHZzQ2hhbmdlOiBFdmVudEVtaXR0ZXI8SVBhZ2VJbmZvPiA9IG5ldyBFdmVudEVtaXR0ZXI8SVBhZ2VJbmZvPigpO1xyXG5cclxuXHRAT3V0cHV0KClcclxuXHRwdWJsaWMgdnNTdGFydDogRXZlbnRFbWl0dGVyPElQYWdlSW5mbz4gPSBuZXcgRXZlbnRFbWl0dGVyPElQYWdlSW5mbz4oKTtcclxuXHJcblx0QE91dHB1dCgpXHJcblx0cHVibGljIHZzRW5kOiBFdmVudEVtaXR0ZXI8SVBhZ2VJbmZvPiA9IG5ldyBFdmVudEVtaXR0ZXI8SVBhZ2VJbmZvPigpO1xyXG5cclxuXHRAVmlld0NoaWxkKCdjb250ZW50JywgeyByZWFkOiBFbGVtZW50UmVmLCBzdGF0aWM6IHRydWUgfSlcclxuXHRwdWJsaWMgY29udGVudEVsZW1lbnRSZWY6IEVsZW1lbnRSZWY7XHJcblxyXG5cdEBWaWV3Q2hpbGQoJ2ludmlzaWJsZVBhZGRpbmcnLCB7IHJlYWQ6IEVsZW1lbnRSZWYsIHN0YXRpYzogdHJ1ZSB9KVxyXG5cdHByb3RlY3RlZCBpbnZpc2libGVQYWRkaW5nRWxlbWVudFJlZjogRWxlbWVudFJlZjtcclxuXHJcblx0QENvbnRlbnRDaGlsZCgnaGVhZGVyJywgeyByZWFkOiBFbGVtZW50UmVmLCBzdGF0aWM6IGZhbHNlIH0pXHJcblx0cHJvdGVjdGVkIGhlYWRlckVsZW1lbnRSZWY6IEVsZW1lbnRSZWY7XHJcblxyXG5cdEBDb250ZW50Q2hpbGQoJ2NvbnRhaW5lcicsIHsgcmVhZDogRWxlbWVudFJlZiwgc3RhdGljOiBmYWxzZSB9KVxyXG5cdHByb3RlY3RlZCBjb250YWluZXJFbGVtZW50UmVmOiBFbGVtZW50UmVmO1xyXG5cclxuXHRwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XHJcblx0XHR0aGlzLmFkZFNjcm9sbEV2ZW50SGFuZGxlcnMoKTtcclxuXHR9XHJcblxyXG5cdHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuXHRcdHRoaXMucmVtb3ZlU2Nyb2xsRXZlbnRIYW5kbGVycygpO1xyXG5cdFx0dGhpcy5yZXZlcnRQYXJlbnRPdmVyc2Nyb2xsKCk7XHJcblx0fVxyXG5cclxuXHRwdWJsaWMgbmdPbkNoYW5nZXMoY2hhbmdlczogYW55KTogdm9pZCB7XHJcblx0XHRjb25zdCBpbmRleExlbmd0aENoYW5nZWQgPSB0aGlzLmNhY2hlZEl0ZW1zTGVuZ3RoICE9PSB0aGlzLml0ZW1zLmxlbmd0aDtcclxuXHRcdHRoaXMuY2FjaGVkSXRlbXNMZW5ndGggPSB0aGlzLml0ZW1zLmxlbmd0aDtcclxuXHJcblx0XHRjb25zdCBmaXJzdFJ1bjogYm9vbGVhbiA9ICFjaGFuZ2VzLml0ZW1zIHx8ICFjaGFuZ2VzLml0ZW1zLnByZXZpb3VzVmFsdWUgfHwgY2hhbmdlcy5pdGVtcy5wcmV2aW91c1ZhbHVlLmxlbmd0aCA9PT0gMDtcclxuXHRcdHRoaXMucmVmcmVzaF9pbnRlcm5hbChpbmRleExlbmd0aENoYW5nZWQgfHwgZmlyc3RSdW4pO1xyXG5cdH1cclxuXHJcblx0cHVibGljIG5nRG9DaGVjaygpOiB2b2lkIHtcclxuXHRcdGlmICh0aGlzLmNhY2hlZEl0ZW1zTGVuZ3RoICE9PSB0aGlzLml0ZW1zLmxlbmd0aCkge1xyXG5cdFx0XHR0aGlzLmNhY2hlZEl0ZW1zTGVuZ3RoID0gdGhpcy5pdGVtcy5sZW5ndGg7XHJcblx0XHRcdHRoaXMucmVmcmVzaF9pbnRlcm5hbCh0cnVlKTtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICh0aGlzLnByZXZpb3VzVmlld1BvcnQgJiYgdGhpcy52aWV3UG9ydEl0ZW1zICYmIHRoaXMudmlld1BvcnRJdGVtcy5sZW5ndGggPiAwKSB7XHJcblx0XHRcdGxldCBpdGVtc0FycmF5Q2hhbmdlZCA9IGZhbHNlO1xyXG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMudmlld1BvcnRJdGVtcy5sZW5ndGg7ICsraSkge1xyXG5cdFx0XHRcdGlmICghdGhpcy5jb21wYXJlSXRlbXModGhpcy5pdGVtc1t0aGlzLnByZXZpb3VzVmlld1BvcnQuc3RhcnRJbmRleFdpdGhCdWZmZXIgKyBpXSwgdGhpcy52aWV3UG9ydEl0ZW1zW2ldKSkge1xyXG5cdFx0XHRcdFx0aXRlbXNBcnJheUNoYW5nZWQgPSB0cnVlO1xyXG5cdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHRcdGlmIChpdGVtc0FycmF5Q2hhbmdlZCkge1xyXG5cdFx0XHRcdHRoaXMucmVmcmVzaF9pbnRlcm5hbCh0cnVlKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cHVibGljIHJlZnJlc2gocmVmcmVzaENvbXBsZXRlZENhbGxiYWNrOiAoKSA9PiB2b2lkID0gdW5kZWZpbmVkKTogdm9pZCB7XHJcblx0XHR0aGlzLnJlZnJlc2hfaW50ZXJuYWwodHJ1ZSwgcmVmcmVzaENvbXBsZXRlZENhbGxiYWNrKTtcclxuXHR9XHJcblxyXG5cdHB1YmxpYyBpbnZhbGlkYXRlQWxsQ2FjaGVkTWVhc3VyZW1lbnRzKCk6IHZvaWQge1xyXG5cdFx0dGhpcy53cmFwR3JvdXBEaW1lbnNpb25zID0ge1xyXG5cdFx0XHRtYXhDaGlsZFNpemVQZXJXcmFwR3JvdXA6IFtdLFxyXG5cdFx0XHRudW1iZXJPZktub3duV3JhcEdyb3VwQ2hpbGRTaXplczogMCxcclxuXHRcdFx0c3VtT2ZLbm93bldyYXBHcm91cENoaWxkV2lkdGhzOiAwLFxyXG5cdFx0XHRzdW1PZktub3duV3JhcEdyb3VwQ2hpbGRIZWlnaHRzOiAwXHJcblx0XHR9O1xyXG5cclxuXHRcdHRoaXMubWluTWVhc3VyZWRDaGlsZFdpZHRoID0gdW5kZWZpbmVkO1xyXG5cdFx0dGhpcy5taW5NZWFzdXJlZENoaWxkSGVpZ2h0ID0gdW5kZWZpbmVkO1xyXG5cclxuXHRcdHRoaXMucmVmcmVzaF9pbnRlcm5hbChmYWxzZSk7XHJcblx0fVxyXG5cclxuXHRwdWJsaWMgaW52YWxpZGF0ZUNhY2hlZE1lYXN1cmVtZW50Rm9ySXRlbShpdGVtOiBhbnkpOiB2b2lkIHtcclxuXHRcdGlmICh0aGlzLmVuYWJsZVVuZXF1YWxDaGlsZHJlblNpemVzKSB7XHJcblx0XHRcdGNvbnN0IGluZGV4ID0gdGhpcy5pdGVtcyAmJiB0aGlzLml0ZW1zLmluZGV4T2YoaXRlbSk7XHJcblx0XHRcdGlmIChpbmRleCA+PSAwKSB7XHJcblx0XHRcdFx0dGhpcy5pbnZhbGlkYXRlQ2FjaGVkTWVhc3VyZW1lbnRBdEluZGV4KGluZGV4KTtcclxuXHRcdFx0fVxyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0dGhpcy5taW5NZWFzdXJlZENoaWxkV2lkdGggPSB1bmRlZmluZWQ7XHJcblx0XHRcdHRoaXMubWluTWVhc3VyZWRDaGlsZEhlaWdodCA9IHVuZGVmaW5lZDtcclxuXHRcdH1cclxuXHJcblx0XHR0aGlzLnJlZnJlc2hfaW50ZXJuYWwoZmFsc2UpO1xyXG5cdH1cclxuXHJcblx0cHVibGljIGludmFsaWRhdGVDYWNoZWRNZWFzdXJlbWVudEF0SW5kZXgoaW5kZXg6IG51bWJlcik6IHZvaWQge1xyXG5cdFx0aWYgKHRoaXMuZW5hYmxlVW5lcXVhbENoaWxkcmVuU2l6ZXMpIHtcclxuXHRcdFx0Y29uc3QgY2FjaGVkTWVhc3VyZW1lbnQgPSB0aGlzLndyYXBHcm91cERpbWVuc2lvbnMubWF4Q2hpbGRTaXplUGVyV3JhcEdyb3VwW2luZGV4XTtcclxuXHRcdFx0aWYgKGNhY2hlZE1lYXN1cmVtZW50KSB7XHJcblx0XHRcdFx0dGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLm1heENoaWxkU2l6ZVBlcldyYXBHcm91cFtpbmRleF0gPSB1bmRlZmluZWQ7XHJcblx0XHRcdFx0LS10aGlzLndyYXBHcm91cERpbWVuc2lvbnMubnVtYmVyT2ZLbm93bldyYXBHcm91cENoaWxkU2l6ZXM7XHJcblx0XHRcdFx0dGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLnN1bU9mS25vd25XcmFwR3JvdXBDaGlsZFdpZHRocyAtPSBjYWNoZWRNZWFzdXJlbWVudC5jaGlsZFdpZHRoIHx8IDA7XHJcblx0XHRcdFx0dGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLnN1bU9mS25vd25XcmFwR3JvdXBDaGlsZEhlaWdodHMgLT0gY2FjaGVkTWVhc3VyZW1lbnQuY2hpbGRIZWlnaHQgfHwgMDtcclxuXHRcdFx0fVxyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0dGhpcy5taW5NZWFzdXJlZENoaWxkV2lkdGggPSB1bmRlZmluZWQ7XHJcblx0XHRcdHRoaXMubWluTWVhc3VyZWRDaGlsZEhlaWdodCA9IHVuZGVmaW5lZDtcclxuXHRcdH1cclxuXHJcblx0XHR0aGlzLnJlZnJlc2hfaW50ZXJuYWwoZmFsc2UpO1xyXG5cdH1cclxuXHJcblx0cHVibGljIHNjcm9sbEludG8oaXRlbTogYW55LCBhbGlnblRvQmVnaW5uaW5nID0gdHJ1ZSwgYWRkaXRpb25hbE9mZnNldCA9IDAsIGFuaW1hdGlvbk1pbGxpc2Vjb25kczogbnVtYmVyID0gdW5kZWZpbmVkLCBhbmltYXRpb25Db21wbGV0ZWRDYWxsYmFjazogKCkgPT4gdm9pZCA9IHVuZGVmaW5lZCk6IHZvaWQge1xyXG5cdFx0Y29uc3QgaW5kZXg6IG51bWJlciA9IHRoaXMuaXRlbXMuaW5kZXhPZihpdGVtKTtcclxuXHRcdGlmIChpbmRleCA9PT0gLTEpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdHRoaXMuc2Nyb2xsVG9JbmRleChpbmRleCwgYWxpZ25Ub0JlZ2lubmluZywgYWRkaXRpb25hbE9mZnNldCwgYW5pbWF0aW9uTWlsbGlzZWNvbmRzLCBhbmltYXRpb25Db21wbGV0ZWRDYWxsYmFjayk7XHJcblx0fVxyXG5cclxuXHRwdWJsaWMgc2Nyb2xsVG9JbmRleChpbmRleDogbnVtYmVyLCBhbGlnblRvQmVnaW5uaW5nID0gdHJ1ZSwgYWRkaXRpb25hbE9mZnNldCA9IDAsIGFuaW1hdGlvbk1pbGxpc2Vjb25kczogbnVtYmVyID0gdW5kZWZpbmVkLCBhbmltYXRpb25Db21wbGV0ZWRDYWxsYmFjazogKCkgPT4gdm9pZCA9IHVuZGVmaW5lZCk6IHZvaWQge1xyXG5cdFx0bGV0IG1heFJldHJpZXMgPSA1O1xyXG5cclxuXHRcdGNvbnN0IHJldHJ5SWZOZWVkZWQgPSAoKSA9PiB7XHJcblx0XHRcdC0tbWF4UmV0cmllcztcclxuXHRcdFx0aWYgKG1heFJldHJpZXMgPD0gMCkge1xyXG5cdFx0XHRcdGlmIChhbmltYXRpb25Db21wbGV0ZWRDYWxsYmFjaykge1xyXG5cdFx0XHRcdFx0YW5pbWF0aW9uQ29tcGxldGVkQ2FsbGJhY2soKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRjb25zdCBkaW1lbnNpb25zID0gdGhpcy5jYWxjdWxhdGVEaW1lbnNpb25zKCk7XHJcblx0XHRcdGNvbnN0IGRlc2lyZWRTdGFydEluZGV4ID0gTWF0aC5taW4oTWF0aC5tYXgoaW5kZXgsIDApLCBkaW1lbnNpb25zLml0ZW1Db3VudCAtIDEpO1xyXG5cdFx0XHRpZiAodGhpcy5wcmV2aW91c1ZpZXdQb3J0LnN0YXJ0SW5kZXggPT09IGRlc2lyZWRTdGFydEluZGV4KSB7XHJcblx0XHRcdFx0aWYgKGFuaW1hdGlvbkNvbXBsZXRlZENhbGxiYWNrKSB7XHJcblx0XHRcdFx0XHRhbmltYXRpb25Db21wbGV0ZWRDYWxsYmFjaygpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHRoaXMuc2Nyb2xsVG9JbmRleF9pbnRlcm5hbChpbmRleCwgYWxpZ25Ub0JlZ2lubmluZywgYWRkaXRpb25hbE9mZnNldCwgMCwgcmV0cnlJZk5lZWRlZCk7XHJcblx0XHR9O1xyXG5cclxuXHRcdHRoaXMuc2Nyb2xsVG9JbmRleF9pbnRlcm5hbChpbmRleCwgYWxpZ25Ub0JlZ2lubmluZywgYWRkaXRpb25hbE9mZnNldCwgYW5pbWF0aW9uTWlsbGlzZWNvbmRzLCByZXRyeUlmTmVlZGVkKTtcclxuXHR9XHJcblxyXG5cdHByb3RlY3RlZCBzY3JvbGxUb0luZGV4X2ludGVybmFsKGluZGV4OiBudW1iZXIsIGFsaWduVG9CZWdpbm5pbmcgPSB0cnVlLCBhZGRpdGlvbmFsT2Zmc2V0ID0gMCwgYW5pbWF0aW9uTWlsbGlzZWNvbmRzOiBudW1iZXIgPSB1bmRlZmluZWQsIGFuaW1hdGlvbkNvbXBsZXRlZENhbGxiYWNrOiAoKSA9PiB2b2lkID0gdW5kZWZpbmVkKTogdm9pZCB7XHJcblx0XHRhbmltYXRpb25NaWxsaXNlY29uZHMgPSBhbmltYXRpb25NaWxsaXNlY29uZHMgPT09IHVuZGVmaW5lZCA/IHRoaXMuc2Nyb2xsQW5pbWF0aW9uVGltZSA6IGFuaW1hdGlvbk1pbGxpc2Vjb25kcztcclxuXHJcblx0XHRjb25zdCBkaW1lbnNpb25zID0gdGhpcy5jYWxjdWxhdGVEaW1lbnNpb25zKCk7XHJcblx0XHRsZXQgc2Nyb2xsID0gdGhpcy5jYWxjdWxhdGVQYWRkaW5nKGluZGV4LCBkaW1lbnNpb25zKSArIGFkZGl0aW9uYWxPZmZzZXQ7XHJcblx0XHRpZiAoIWFsaWduVG9CZWdpbm5pbmcpIHtcclxuXHRcdFx0c2Nyb2xsIC09IGRpbWVuc2lvbnMud3JhcEdyb3Vwc1BlclBhZ2UgKiBkaW1lbnNpb25zW3RoaXMuX2NoaWxkU2Nyb2xsRGltXTtcclxuXHRcdH1cclxuXHJcblx0XHR0aGlzLnNjcm9sbFRvUG9zaXRpb24oc2Nyb2xsLCBhbmltYXRpb25NaWxsaXNlY29uZHMsIGFuaW1hdGlvbkNvbXBsZXRlZENhbGxiYWNrKTtcclxuXHR9XHJcblxyXG5cdHB1YmxpYyBzY3JvbGxUb1Bvc2l0aW9uKHNjcm9sbFBvc2l0aW9uOiBudW1iZXIsIGFuaW1hdGlvbk1pbGxpc2Vjb25kczogbnVtYmVyID0gdW5kZWZpbmVkLCBhbmltYXRpb25Db21wbGV0ZWRDYWxsYmFjazogKCkgPT4gdm9pZCA9IHVuZGVmaW5lZCk6IHZvaWQge1xyXG5cdFx0c2Nyb2xsUG9zaXRpb24gKz0gdGhpcy5nZXRFbGVtZW50c09mZnNldCgpO1xyXG5cclxuXHRcdGFuaW1hdGlvbk1pbGxpc2Vjb25kcyA9IGFuaW1hdGlvbk1pbGxpc2Vjb25kcyA9PT0gdW5kZWZpbmVkID8gdGhpcy5zY3JvbGxBbmltYXRpb25UaW1lIDogYW5pbWF0aW9uTWlsbGlzZWNvbmRzO1xyXG5cclxuXHRcdGNvbnN0IHNjcm9sbEVsZW1lbnQgPSB0aGlzLmdldFNjcm9sbEVsZW1lbnQoKTtcclxuXHJcblx0XHRsZXQgYW5pbWF0aW9uUmVxdWVzdDogbnVtYmVyO1xyXG5cclxuXHRcdGlmICh0aGlzLmN1cnJlbnRUd2Vlbikge1xyXG5cdFx0XHR0aGlzLmN1cnJlbnRUd2Vlbi5zdG9wKCk7XHJcblx0XHRcdHRoaXMuY3VycmVudFR3ZWVuID0gdW5kZWZpbmVkO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICghYW5pbWF0aW9uTWlsbGlzZWNvbmRzKSB7XHJcblx0XHRcdHRoaXMucmVuZGVyZXIuc2V0UHJvcGVydHkoc2Nyb2xsRWxlbWVudCwgdGhpcy5fc2Nyb2xsVHlwZSwgc2Nyb2xsUG9zaXRpb24pO1xyXG5cdFx0XHR0aGlzLnJlZnJlc2hfaW50ZXJuYWwoZmFsc2UsIGFuaW1hdGlvbkNvbXBsZXRlZENhbGxiYWNrKTtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdGNvbnN0IHR3ZWVuQ29uZmlnT2JqID0geyBzY3JvbGxQb3NpdGlvbjogc2Nyb2xsRWxlbWVudFt0aGlzLl9zY3JvbGxUeXBlXSB9O1xyXG5cclxuXHRcdGNvbnN0IG5ld1R3ZWVuID0gbmV3IHR3ZWVuLlR3ZWVuKHR3ZWVuQ29uZmlnT2JqKVxyXG5cdFx0XHQudG8oeyBzY3JvbGxQb3NpdGlvbiB9LCBhbmltYXRpb25NaWxsaXNlY29uZHMpXHJcblx0XHRcdC5lYXNpbmcodHdlZW4uRWFzaW5nLlF1YWRyYXRpYy5PdXQpXHJcblx0XHRcdC5vblVwZGF0ZSgoZGF0YSkgPT4ge1xyXG5cdFx0XHRcdGlmIChpc05hTihkYXRhLnNjcm9sbFBvc2l0aW9uKSkge1xyXG5cdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHR0aGlzLnJlbmRlcmVyLnNldFByb3BlcnR5KHNjcm9sbEVsZW1lbnQsIHRoaXMuX3Njcm9sbFR5cGUsIGRhdGEuc2Nyb2xsUG9zaXRpb24pO1xyXG5cdFx0XHRcdHRoaXMucmVmcmVzaF9pbnRlcm5hbChmYWxzZSk7XHJcblx0XHRcdH0pXHJcblx0XHRcdC5vblN0b3AoKCkgPT4ge1xyXG5cdFx0XHRcdGNhbmNlbEFuaW1hdGlvbkZyYW1lKGFuaW1hdGlvblJlcXVlc3QpO1xyXG5cdFx0XHR9KVxyXG5cdFx0XHQuc3RhcnQoKTtcclxuXHJcblx0XHRjb25zdCBhbmltYXRlID0gKHRpbWU/OiBudW1iZXIpID0+IHtcclxuXHRcdFx0aWYgKCFuZXdUd2VlbltcImlzUGxheWluZ1wiXSgpKSB7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRuZXdUd2Vlbi51cGRhdGUodGltZSk7XHJcblx0XHRcdGlmICh0d2VlbkNvbmZpZ09iai5zY3JvbGxQb3NpdGlvbiA9PT0gc2Nyb2xsUG9zaXRpb24pIHtcclxuXHRcdFx0XHR0aGlzLnJlZnJlc2hfaW50ZXJuYWwoZmFsc2UsIGFuaW1hdGlvbkNvbXBsZXRlZENhbGxiYWNrKTtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHRoaXMuem9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XHJcblx0XHRcdFx0YW5pbWF0aW9uUmVxdWVzdCA9IHJlcXVlc3RBbmltYXRpb25GcmFtZShhbmltYXRlKTtcclxuXHRcdFx0fSk7XHJcblx0XHR9O1xyXG5cclxuXHRcdGFuaW1hdGUoKTtcclxuXHRcdHRoaXMuY3VycmVudFR3ZWVuID0gbmV3VHdlZW47XHJcblx0fVxyXG5cclxuXHRwcm90ZWN0ZWQgaXNBbmd1bGFyVW5pdmVyc2FsU1NSOiBib29sZWFuO1xyXG5cclxuXHRjb25zdHJ1Y3RvcihcclxuXHRcdHByb3RlY3RlZCByZWFkb25seSBlbGVtZW50OiBFbGVtZW50UmVmLFxyXG5cdFx0cHJvdGVjdGVkIHJlYWRvbmx5IHJlbmRlcmVyOiBSZW5kZXJlcjIsXHJcblx0XHRwcm90ZWN0ZWQgcmVhZG9ubHkgem9uZTogTmdab25lLFxyXG5cdFx0cHJvdGVjdGVkIGNoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZixcclxuXHRcdEBJbmplY3QoUExBVEZPUk1fSUQpIHBsYXRmb3JtSWQ6IGFueSxcclxuXHRcdEBPcHRpb25hbCgpIEBJbmplY3QoJ3ZpcnR1YWwtc2Nyb2xsZXItZGVmYXVsdC1vcHRpb25zJylcclxuXHRcdG9wdGlvbnM6IFZpcnR1YWxTY3JvbGxlckRlZmF1bHRPcHRpb25zXHJcblx0KSB7XHJcblxyXG5cdFx0dGhpcy5pc0FuZ3VsYXJVbml2ZXJzYWxTU1IgPSBpc1BsYXRmb3JtU2VydmVyKHBsYXRmb3JtSWQpO1xyXG5cclxuXHRcdGNvbnN0IGRlZmF1bHRPcHRpb25zID0gVklSVFVBTF9TQ1JPTExFUl9ERUZBVUxUX09QVElPTlNfRkFDVE9SWSgpO1xyXG5cclxuXHRcdHRoaXMuY2hlY2tSZXNpemVJbnRlcnZhbCA9IG9wdGlvbnM/LmNoZWNrUmVzaXplSW50ZXJ2YWwgfHwgZGVmYXVsdE9wdGlvbnMuY2hlY2tSZXNpemVJbnRlcnZhbDtcclxuXHRcdHRoaXMubW9kaWZ5T3ZlcmZsb3dTdHlsZU9mUGFyZW50U2Nyb2xsID0gb3B0aW9ucz8ubW9kaWZ5T3ZlcmZsb3dTdHlsZU9mUGFyZW50U2Nyb2xsIHx8IGRlZmF1bHRPcHRpb25zLm1vZGlmeU92ZXJmbG93U3R5bGVPZlBhcmVudFNjcm9sbDtcclxuXHRcdHRoaXMucmVzaXplQnlwYXNzUmVmcmVzaFRocmVzaG9sZCA9IG9wdGlvbnM/LnJlc2l6ZUJ5cGFzc1JlZnJlc2hUaHJlc2hvbGQgfHwgZGVmYXVsdE9wdGlvbnMucmVzaXplQnlwYXNzUmVmcmVzaFRocmVzaG9sZDtcclxuXHRcdHRoaXMuc2Nyb2xsQW5pbWF0aW9uVGltZSA9IG9wdGlvbnM/LnNjcm9sbEFuaW1hdGlvblRpbWUgfHwgZGVmYXVsdE9wdGlvbnMuc2Nyb2xsQW5pbWF0aW9uVGltZTtcclxuXHRcdHRoaXMuc2Nyb2xsRGVib3VuY2VUaW1lID0gb3B0aW9ucz8uc2Nyb2xsRGVib3VuY2VUaW1lIHx8IGRlZmF1bHRPcHRpb25zLnNjcm9sbERlYm91bmNlVGltZTtcclxuXHRcdHRoaXMuc2Nyb2xsVGhyb3R0bGluZ1RpbWUgPSBvcHRpb25zPy5zY3JvbGxUaHJvdHRsaW5nVGltZSB8fCBkZWZhdWx0T3B0aW9ucy5zY3JvbGxUaHJvdHRsaW5nVGltZTtcclxuXHRcdHRoaXMuc2Nyb2xsYmFySGVpZ2h0ID0gb3B0aW9ucz8uc2Nyb2xsYmFySGVpZ2h0IHx8IGRlZmF1bHRPcHRpb25zLnNjcm9sbGJhckhlaWdodDtcclxuXHRcdHRoaXMuc2Nyb2xsYmFyV2lkdGggPSBvcHRpb25zPy5zY3JvbGxiYXJXaWR0aCB8fCBkZWZhdWx0T3B0aW9ucy5zY3JvbGxiYXJXaWR0aDtcclxuXHRcdHRoaXMuc3RyaXBlZFRhYmxlID0gb3B0aW9ucz8uc3RyaXBlZFRhYmxlIHx8IGRlZmF1bHRPcHRpb25zLnN0cmlwZWRUYWJsZTtcclxuXHJcblx0XHR0aGlzLmhvcml6b250YWwgPSBmYWxzZTtcclxuXHRcdHRoaXMucmVzZXRXcmFwR3JvdXBEaW1lbnNpb25zKCk7XHJcblx0fVxyXG5cclxuXHRwdWJsaWMgZ2V0RWxlbWVudFNpemUoZWxlbWVudDogSFRNTEVsZW1lbnQpOiBhbnkge1xyXG5cdFx0Y29uc3QgcmVzdWx0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuXHRcdGNvbnN0IHN0eWxlcyA9IGdldENvbXB1dGVkU3R5bGUoZWxlbWVudCk7XHJcblx0XHRjb25zdCBtYXJnaW5Ub3AgPSBwYXJzZUludChzdHlsZXNbJ21hcmdpbi10b3AnXSwgMTApIHx8IDA7XHJcblx0XHRjb25zdCBtYXJnaW5Cb3R0b20gPSBwYXJzZUludChzdHlsZXNbJ21hcmdpbi1ib3R0b20nXSwgMTApIHx8IDA7XHJcblx0XHRjb25zdCBtYXJnaW5MZWZ0ID0gcGFyc2VJbnQoc3R5bGVzWydtYXJnaW4tbGVmdCddLCAxMCkgfHwgMDtcclxuXHRcdGNvbnN0IG1hcmdpblJpZ2h0ID0gcGFyc2VJbnQoc3R5bGVzWydtYXJnaW4tcmlnaHQnXSwgMTApIHx8IDA7XHJcblxyXG5cdFx0cmV0dXJuIHtcclxuXHRcdFx0dG9wOiByZXN1bHQudG9wICsgbWFyZ2luVG9wLFxyXG5cdFx0XHRib3R0b206IHJlc3VsdC5ib3R0b20gKyBtYXJnaW5Cb3R0b20sXHJcblx0XHRcdGxlZnQ6IHJlc3VsdC5sZWZ0ICsgbWFyZ2luTGVmdCxcclxuXHRcdFx0cmlnaHQ6IHJlc3VsdC5yaWdodCArIG1hcmdpblJpZ2h0LFxyXG5cdFx0XHR3aWR0aDogcmVzdWx0LndpZHRoICsgbWFyZ2luTGVmdCArIG1hcmdpblJpZ2h0LFxyXG5cdFx0XHRoZWlnaHQ6IHJlc3VsdC5oZWlnaHQgKyBtYXJnaW5Ub3AgKyBtYXJnaW5Cb3R0b21cclxuXHRcdH07XHJcblx0fVxyXG5cclxuXHRwdWJsaWMgZ2V0Q29udGVudCgpIHtcclxuXHRcdGNvbnN0IGNvbnRlbnQgPSAodGhpcy5jb250YWluZXJFbGVtZW50UmVmICYmIHRoaXMuY29udGFpbmVyRWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KSB8fCB0aGlzLmNvbnRlbnRFbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XHJcblx0XHRyZXR1cm4gY29udGVudDtcclxuXHR9XHJcblxyXG5cdHByb3RlY3RlZCBwcmV2aW91c1Njcm9sbEJvdW5kaW5nUmVjdDogRE9NUmVjdDtcclxuXHRwcm90ZWN0ZWQgY2hlY2tTY3JvbGxFbGVtZW50UmVzaXplZCgpOiB2b2lkIHtcclxuXHRcdGNvbnN0IGJvdW5kaW5nUmVjdCA9IHRoaXMuZ2V0RWxlbWVudFNpemUodGhpcy5nZXRTY3JvbGxFbGVtZW50KCkpO1xyXG5cclxuXHRcdGxldCBzaXplQ2hhbmdlZDogYm9vbGVhbjtcclxuXHRcdGlmICghdGhpcy5wcmV2aW91c1Njcm9sbEJvdW5kaW5nUmVjdCkge1xyXG5cdFx0XHRzaXplQ2hhbmdlZCA9IHRydWU7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRjb25zdCB3aWR0aENoYW5nZSA9IE1hdGguYWJzKGJvdW5kaW5nUmVjdC53aWR0aCAtIHRoaXMucHJldmlvdXNTY3JvbGxCb3VuZGluZ1JlY3Qud2lkdGgpO1xyXG5cdFx0XHRjb25zdCBoZWlnaHRDaGFuZ2UgPSBNYXRoLmFicyhib3VuZGluZ1JlY3QuaGVpZ2h0IC0gdGhpcy5wcmV2aW91c1Njcm9sbEJvdW5kaW5nUmVjdC5oZWlnaHQpO1xyXG5cdFx0XHRzaXplQ2hhbmdlZCA9IHdpZHRoQ2hhbmdlID4gdGhpcy5yZXNpemVCeXBhc3NSZWZyZXNoVGhyZXNob2xkIHx8IGhlaWdodENoYW5nZSA+IHRoaXMucmVzaXplQnlwYXNzUmVmcmVzaFRocmVzaG9sZDtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoc2l6ZUNoYW5nZWQpIHtcclxuXHRcdFx0dGhpcy5wcmV2aW91c1Njcm9sbEJvdW5kaW5nUmVjdCA9IGJvdW5kaW5nUmVjdDtcclxuXHRcdFx0aWYgKGJvdW5kaW5nUmVjdC53aWR0aCA+IDAgJiYgYm91bmRpbmdSZWN0LmhlaWdodCA+IDApIHtcclxuXHRcdFx0XHR0aGlzLnJlZnJlc2hfaW50ZXJuYWwoZmFsc2UpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRwcm90ZWN0ZWQgX2ludmlzaWJsZVBhZGRpbmdQcm9wZXJ0eTtcclxuXHRwcm90ZWN0ZWQgX29mZnNldFR5cGU7XHJcblx0cHJvdGVjdGVkIF9zY3JvbGxUeXBlO1xyXG5cdHByb3RlY3RlZCBfcGFnZU9mZnNldFR5cGU7XHJcblx0cHJvdGVjdGVkIF9jaGlsZFNjcm9sbERpbTtcclxuXHRwcm90ZWN0ZWQgX3RyYW5zbGF0ZURpcjtcclxuXHRwcm90ZWN0ZWQgX21hcmdpbkRpcjtcclxuXHRwcm90ZWN0ZWQgdXBkYXRlRGlyZWN0aW9uKCk6IHZvaWQge1xyXG5cdFx0aWYgKHRoaXMuaG9yaXpvbnRhbCkge1xyXG5cdFx0XHR0aGlzLl9jaGlsZFNjcm9sbERpbSA9ICdjaGlsZFdpZHRoJztcclxuXHRcdFx0dGhpcy5faW52aXNpYmxlUGFkZGluZ1Byb3BlcnR5ID0gJ3NjYWxlWCc7XHJcblx0XHRcdHRoaXMuX21hcmdpbkRpciA9ICdtYXJnaW4tbGVmdCc7XHJcblx0XHRcdHRoaXMuX29mZnNldFR5cGUgPSAnb2Zmc2V0TGVmdCc7XHJcblx0XHRcdHRoaXMuX3BhZ2VPZmZzZXRUeXBlID0gJ3BhZ2VYT2Zmc2V0JztcclxuXHRcdFx0dGhpcy5fc2Nyb2xsVHlwZSA9ICdzY3JvbGxMZWZ0JztcclxuXHRcdFx0dGhpcy5fdHJhbnNsYXRlRGlyID0gJ3RyYW5zbGF0ZVgnO1xyXG5cdFx0fVxyXG5cdFx0ZWxzZSB7XHJcblx0XHRcdHRoaXMuX2NoaWxkU2Nyb2xsRGltID0gJ2NoaWxkSGVpZ2h0JztcclxuXHRcdFx0dGhpcy5faW52aXNpYmxlUGFkZGluZ1Byb3BlcnR5ID0gJ3NjYWxlWSc7XHJcblx0XHRcdHRoaXMuX21hcmdpbkRpciA9ICdtYXJnaW4tdG9wJztcclxuXHRcdFx0dGhpcy5fb2Zmc2V0VHlwZSA9ICdvZmZzZXRUb3AnO1xyXG5cdFx0XHR0aGlzLl9wYWdlT2Zmc2V0VHlwZSA9ICdwYWdlWU9mZnNldCc7XHJcblx0XHRcdHRoaXMuX3Njcm9sbFR5cGUgPSAnc2Nyb2xsVG9wJztcclxuXHRcdFx0dGhpcy5fdHJhbnNsYXRlRGlyID0gJ3RyYW5zbGF0ZVknO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cHJvdGVjdGVkIGRlYm91bmNlKGZ1bmM6ICgpID0+IHZvaWQsIHdhaXQ6IG51bWJlciwgLi4uYXJncyk6ICgpID0+IHZvaWQge1xyXG5cdFx0Y29uc3QgdGhyb3R0bGVkID0gdGhpcy50aHJvdHRsZVRyYWlsaW5nKGZ1bmMsIHdhaXQpO1xyXG5cdFx0Y29uc3QgcmVzdWx0ID0gZnVuY3Rpb24gKCkge1xyXG5cdFx0XHR0aHJvdHRsZWRbJ2NhbmNlbCddKCk7XHJcblx0XHRcdHRocm90dGxlZC5hcHBseSh0aGlzLCBhcmdzKTtcclxuXHRcdH07XHJcblx0XHRyZXN1bHRbJ2NhbmNlbCddID0gZnVuY3Rpb24gKCkge1xyXG5cdFx0XHR0aHJvdHRsZWRbJ2NhbmNlbCddKCk7XHJcblx0XHR9O1xyXG5cclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRwcm90ZWN0ZWQgdGhyb3R0bGVUcmFpbGluZyhmdW5jOiAoKSA9PiB2b2lkLCB3YWl0OiBudW1iZXIsIC4uLmFyZ3MpOiAoKSA9PiB2b2lkIHtcclxuXHRcdGxldCB0aW1lb3V0ID0gdW5kZWZpbmVkO1xyXG5cdFx0bGV0IF9hcmd1bWVudHMgPSBhcmdzO1xyXG5cdFx0Y29uc3QgcmVzdWx0ID0gZnVuY3Rpb24gKCkge1xyXG5cdFx0XHRjb25zdCBfdGhpcyA9IHRoaXM7XHJcblx0XHRcdF9hcmd1bWVudHMgPSBhcmdzXHJcblxyXG5cdFx0XHRpZiAodGltZW91dCkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aWYgKHdhaXQgPD0gMCkge1xyXG5cdFx0XHRcdGZ1bmMuYXBwbHkoX3RoaXMsIF9hcmd1bWVudHMpO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdHRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuXHRcdFx0XHRcdHRpbWVvdXQgPSB1bmRlZmluZWQ7XHJcblx0XHRcdFx0XHRmdW5jLmFwcGx5KF90aGlzLCBfYXJndW1lbnRzKTtcclxuXHRcdFx0XHR9LCB3YWl0KTtcclxuXHRcdFx0fVxyXG5cdFx0fTtcclxuXHRcdHJlc3VsdFsnY2FuY2VsJ10gPSBmdW5jdGlvbiAoKSB7XHJcblx0XHRcdGlmICh0aW1lb3V0KSB7XHJcblx0XHRcdFx0Y2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xyXG5cdFx0XHRcdHRpbWVvdXQgPSB1bmRlZmluZWQ7XHJcblx0XHRcdH1cclxuXHRcdH07XHJcblxyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHByb3RlY3RlZCBjYWxjdWxhdGVkU2Nyb2xsYmFyV2lkdGggPSAwO1xyXG5cdHByb3RlY3RlZCBjYWxjdWxhdGVkU2Nyb2xsYmFySGVpZ2h0ID0gMDtcclxuXHJcblx0cHJvdGVjdGVkIHBhZGRpbmcgPSAwO1xyXG5cdHByb3RlY3RlZCBwcmV2aW91c1ZpZXdQb3J0OiBJVmlld3BvcnQgPSA8YW55Pnt9O1xyXG5cdHByb3RlY3RlZCBjdXJyZW50VHdlZW46IHR3ZWVuLlR3ZWVuO1xyXG5cdHByb3RlY3RlZCBjYWNoZWRJdGVtc0xlbmd0aDogbnVtYmVyO1xyXG5cclxuXHRwcm90ZWN0ZWQgZGlzcG9zZVNjcm9sbEhhbmRsZXI6ICgpID0+IHZvaWQgfCB1bmRlZmluZWQ7XHJcblx0cHJvdGVjdGVkIGRpc3Bvc2VSZXNpemVIYW5kbGVyOiAoKSA9PiB2b2lkIHwgdW5kZWZpbmVkO1xyXG5cclxuXHRwcm90ZWN0ZWQgcmVmcmVzaF9pbnRlcm5hbChpdGVtc0FycmF5TW9kaWZpZWQ6IGJvb2xlYW4sIHJlZnJlc2hDb21wbGV0ZWRDYWxsYmFjazogKCkgPT4gdm9pZCA9IHVuZGVmaW5lZCwgbWF4UnVuVGltZXMgPSAyKTogdm9pZCB7XHJcblx0XHQvL25vdGU6IG1heFJ1blRpbWVzIGlzIHRvIGZvcmNlIGl0IHRvIGtlZXAgcmVjYWxjdWxhdGluZyBpZiB0aGUgcHJldmlvdXMgaXRlcmF0aW9uIGNhdXNlZCBhIHJlLXJlbmRlciAoZGlmZmVyZW50IHNsaWNlZCBpdGVtcyBpbiB2aWV3cG9ydCBvciBzY3JvbGxQb3NpdGlvbiBjaGFuZ2VkKS5cclxuXHRcdC8vVGhlIGRlZmF1bHQgb2YgMnggbWF4IHdpbGwgcHJvYmFibHkgYmUgYWNjdXJhdGUgZW5vdWdoIHdpdGhvdXQgY2F1c2luZyB0b28gbGFyZ2UgYSBwZXJmb3JtYW5jZSBib3R0bGVuZWNrXHJcblx0XHQvL1RoZSBjb2RlIHdvdWxkIHR5cGljYWxseSBxdWl0IG91dCBvbiB0aGUgMm5kIGl0ZXJhdGlvbiBhbnl3YXlzLiBUaGUgbWFpbiB0aW1lIGl0J2QgdGhpbmsgbW9yZSB0aGFuIDIgcnVucyB3b3VsZCBiZSBuZWNlc3Nhcnkgd291bGQgYmUgZm9yIHZhc3RseSBkaWZmZXJlbnQgc2l6ZWQgY2hpbGQgaXRlbXMgb3IgaWYgdGhpcyBpcyB0aGUgMXN0IHRpbWUgdGhlIGl0ZW1zIGFycmF5IHdhcyBpbml0aWFsaXplZC5cclxuXHRcdC8vV2l0aG91dCBtYXhSdW5UaW1lcywgSWYgdGhlIHVzZXIgaXMgYWN0aXZlbHkgc2Nyb2xsaW5nIHRoaXMgY29kZSB3b3VsZCBiZWNvbWUgYW4gaW5maW5pdGUgbG9vcCB1bnRpbCB0aGV5IHN0b3BwZWQgc2Nyb2xsaW5nLiBUaGlzIHdvdWxkIGJlIG9rYXksIGV4Y2VwdCBlYWNoIHNjcm9sbCBldmVudCB3b3VsZCBzdGFydCBhbiBhZGRpdGlvbmFsIGluZmludGUgbG9vcC4gV2Ugd2FudCB0byBzaG9ydC1jaXJjdWl0IGl0IHRvIHByZXZlbnQgdGhpcy5cclxuXHJcblx0XHRpZiAoaXRlbXNBcnJheU1vZGlmaWVkICYmIHRoaXMucHJldmlvdXNWaWV3UG9ydCAmJiB0aGlzLnByZXZpb3VzVmlld1BvcnQuc2Nyb2xsU3RhcnRQb3NpdGlvbiA+IDApIHtcclxuXHRcdFx0Ly9pZiBpdGVtcyB3ZXJlIHByZXBlbmRlZCwgc2Nyb2xsIGZvcndhcmQgdG8ga2VlcCBzYW1lIGl0ZW1zIHZpc2libGVcclxuXHRcdFx0Y29uc3Qgb2xkVmlld1BvcnQgPSB0aGlzLnByZXZpb3VzVmlld1BvcnQ7XHJcblx0XHRcdGNvbnN0IG9sZFZpZXdQb3J0SXRlbXMgPSB0aGlzLnZpZXdQb3J0SXRlbXM7XHJcblxyXG5cdFx0XHRjb25zdCBvbGRSZWZyZXNoQ29tcGxldGVkQ2FsbGJhY2sgPSByZWZyZXNoQ29tcGxldGVkQ2FsbGJhY2s7XHJcblx0XHRcdHJlZnJlc2hDb21wbGV0ZWRDYWxsYmFjayA9ICgpID0+IHtcclxuXHRcdFx0XHRjb25zdCBzY3JvbGxMZW5ndGhEZWx0YSA9IHRoaXMucHJldmlvdXNWaWV3UG9ydC5zY3JvbGxMZW5ndGggLSBvbGRWaWV3UG9ydC5zY3JvbGxMZW5ndGg7XHJcblx0XHRcdFx0aWYgKHNjcm9sbExlbmd0aERlbHRhID4gMCAmJiB0aGlzLnZpZXdQb3J0SXRlbXMpIHtcclxuXHRcdFx0XHRcdGNvbnN0IG9sZFN0YXJ0SXRlbSA9IG9sZFZpZXdQb3J0SXRlbXNbMF07XHJcblx0XHRcdFx0XHRjb25zdCBvbGRTdGFydEl0ZW1JbmRleCA9IHRoaXMuaXRlbXMuZmluZEluZGV4KHggPT4gdGhpcy5jb21wYXJlSXRlbXMob2xkU3RhcnRJdGVtLCB4KSk7XHJcblx0XHRcdFx0XHRpZiAob2xkU3RhcnRJdGVtSW5kZXggPiB0aGlzLnByZXZpb3VzVmlld1BvcnQuc3RhcnRJbmRleFdpdGhCdWZmZXIpIHtcclxuXHRcdFx0XHRcdFx0bGV0IGl0ZW1PcmRlckNoYW5nZWQgPSBmYWxzZTtcclxuXHRcdFx0XHRcdFx0Zm9yIChsZXQgaSA9IDE7IGkgPCB0aGlzLnZpZXdQb3J0SXRlbXMubGVuZ3RoOyArK2kpIHtcclxuXHRcdFx0XHRcdFx0XHRpZiAoIXRoaXMuY29tcGFyZUl0ZW1zKHRoaXMuaXRlbXNbb2xkU3RhcnRJdGVtSW5kZXggKyBpXSwgb2xkVmlld1BvcnRJdGVtc1tpXSkpIHtcclxuXHRcdFx0XHRcdFx0XHRcdGl0ZW1PcmRlckNoYW5nZWQgPSB0cnVlO1xyXG5cdFx0XHRcdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0XHRpZiAoIWl0ZW1PcmRlckNoYW5nZWQpIHtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLnNjcm9sbFRvUG9zaXRpb24odGhpcy5wcmV2aW91c1ZpZXdQb3J0LnNjcm9sbFN0YXJ0UG9zaXRpb24gKyBzY3JvbGxMZW5ndGhEZWx0YSwgMCwgb2xkUmVmcmVzaENvbXBsZXRlZENhbGxiYWNrKTtcclxuXHRcdFx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdGlmIChvbGRSZWZyZXNoQ29tcGxldGVkQ2FsbGJhY2spIHtcclxuXHRcdFx0XHRcdG9sZFJlZnJlc2hDb21wbGV0ZWRDYWxsYmFjaygpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fTtcclxuXHRcdH1cclxuXHJcblx0XHR0aGlzLnpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xyXG5cdFx0XHRyZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xyXG5cclxuXHRcdFx0XHRpZiAoaXRlbXNBcnJheU1vZGlmaWVkKSB7XHJcblx0XHRcdFx0XHR0aGlzLnJlc2V0V3JhcEdyb3VwRGltZW5zaW9ucygpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRjb25zdCB2aWV3cG9ydCA9IHRoaXMuY2FsY3VsYXRlVmlld3BvcnQoKTtcclxuXHJcblx0XHRcdFx0Y29uc3Qgc3RhcnRDaGFuZ2VkID0gaXRlbXNBcnJheU1vZGlmaWVkIHx8IHZpZXdwb3J0LnN0YXJ0SW5kZXggIT09IHRoaXMucHJldmlvdXNWaWV3UG9ydC5zdGFydEluZGV4O1xyXG5cdFx0XHRcdGNvbnN0IGVuZENoYW5nZWQgPSBpdGVtc0FycmF5TW9kaWZpZWQgfHwgdmlld3BvcnQuZW5kSW5kZXggIT09IHRoaXMucHJldmlvdXNWaWV3UG9ydC5lbmRJbmRleDtcclxuXHRcdFx0XHRjb25zdCBzY3JvbGxMZW5ndGhDaGFuZ2VkID0gdmlld3BvcnQuc2Nyb2xsTGVuZ3RoICE9PSB0aGlzLnByZXZpb3VzVmlld1BvcnQuc2Nyb2xsTGVuZ3RoO1xyXG5cdFx0XHRcdGNvbnN0IHBhZGRpbmdDaGFuZ2VkID0gdmlld3BvcnQucGFkZGluZyAhPT0gdGhpcy5wcmV2aW91c1ZpZXdQb3J0LnBhZGRpbmc7XHJcblx0XHRcdFx0Y29uc3Qgc2Nyb2xsUG9zaXRpb25DaGFuZ2VkID0gdmlld3BvcnQuc2Nyb2xsU3RhcnRQb3NpdGlvbiAhPT0gdGhpcy5wcmV2aW91c1ZpZXdQb3J0LnNjcm9sbFN0YXJ0UG9zaXRpb24gfHwgdmlld3BvcnQuc2Nyb2xsRW5kUG9zaXRpb24gIT09IHRoaXMucHJldmlvdXNWaWV3UG9ydC5zY3JvbGxFbmRQb3NpdGlvbiB8fCB2aWV3cG9ydC5tYXhTY3JvbGxQb3NpdGlvbiAhPT0gdGhpcy5wcmV2aW91c1ZpZXdQb3J0Lm1heFNjcm9sbFBvc2l0aW9uO1xyXG5cclxuXHRcdFx0XHRjb25zdCBzY3JvbGxEaXJlY3Rpb246IFNjcm9sbERpcmVjdGlvblR5cGUgPSB0aGlzLnByZXZpb3VzVmlld1BvcnQuZW5kSW5kZXggPD0gdmlld3BvcnQuZW5kSW5kZXggPyAnZm9yd2FyZCcgOiAnYmFja3dhcmQnO1xyXG5cdFx0XHRcdHRoaXMucHJldmlvdXNWaWV3UG9ydCA9IHZpZXdwb3J0O1xyXG5cclxuXHRcdFx0XHRpZiAoc2Nyb2xsTGVuZ3RoQ2hhbmdlZCkge1xyXG5cdFx0XHRcdFx0dGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmludmlzaWJsZVBhZGRpbmdFbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsICd0cmFuc2Zvcm0nLCBgJHt0aGlzLl9pbnZpc2libGVQYWRkaW5nUHJvcGVydHl9KCR7dmlld3BvcnQuc2Nyb2xsTGVuZ3RofSlgKTtcclxuXHRcdFx0XHRcdHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5pbnZpc2libGVQYWRkaW5nRWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCAnd2Via2l0VHJhbnNmb3JtJywgYCR7dGhpcy5faW52aXNpYmxlUGFkZGluZ1Byb3BlcnR5fSgke3ZpZXdwb3J0LnNjcm9sbExlbmd0aH0pYCk7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRpZiAocGFkZGluZ0NoYW5nZWQpIHtcclxuXHRcdFx0XHRcdGlmICh0aGlzLnVzZU1hcmdpbkluc3RlYWRPZlRyYW5zbGF0ZSkge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHRoaXMuY29udGVudEVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgdGhpcy5fbWFyZ2luRGlyLCBgJHt2aWV3cG9ydC5wYWRkaW5nfXB4YCk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRlbHNlIHtcclxuXHRcdFx0XHRcdFx0dGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmNvbnRlbnRFbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsICd0cmFuc2Zvcm0nLCBgJHt0aGlzLl90cmFuc2xhdGVEaXJ9KCR7dmlld3BvcnQucGFkZGluZ31weClgKTtcclxuXHRcdFx0XHRcdFx0dGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmNvbnRlbnRFbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsICd3ZWJraXRUcmFuc2Zvcm0nLCBgJHt0aGlzLl90cmFuc2xhdGVEaXJ9KCR7dmlld3BvcnQucGFkZGluZ31weClgKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdGlmICh0aGlzLmhlYWRlckVsZW1lbnRSZWYpIHtcclxuXHRcdFx0XHRcdGNvbnN0IHNjcm9sbFBvc2l0aW9uID0gdGhpcy5nZXRTY3JvbGxFbGVtZW50KClbdGhpcy5fc2Nyb2xsVHlwZV07XHJcblx0XHRcdFx0XHRjb25zdCBjb250YWluZXJPZmZzZXQgPSB0aGlzLmdldEVsZW1lbnRzT2Zmc2V0KCk7XHJcblx0XHRcdFx0XHRjb25zdCBvZmZzZXQgPSBNYXRoLm1heChzY3JvbGxQb3NpdGlvbiAtIHZpZXdwb3J0LnBhZGRpbmcgLSBjb250YWluZXJPZmZzZXQgKyB0aGlzLmhlYWRlckVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5jbGllbnRIZWlnaHQsIDApO1xyXG5cdFx0XHRcdFx0dGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmhlYWRlckVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgJ3RyYW5zZm9ybScsIGAke3RoaXMuX3RyYW5zbGF0ZURpcn0oJHtvZmZzZXR9cHgpYCk7XHJcblx0XHRcdFx0XHR0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHRoaXMuaGVhZGVyRWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCAnd2Via2l0VHJhbnNmb3JtJywgYCR7dGhpcy5fdHJhbnNsYXRlRGlyfSgke29mZnNldH1weClgKTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdGNvbnN0IGNoYW5nZUV2ZW50QXJnOiBJUGFnZUluZm8gPSAoc3RhcnRDaGFuZ2VkIHx8IGVuZENoYW5nZWQpID8ge1xyXG5cdFx0XHRcdFx0c3RhcnRJbmRleDogdmlld3BvcnQuc3RhcnRJbmRleCxcclxuXHRcdFx0XHRcdGVuZEluZGV4OiB2aWV3cG9ydC5lbmRJbmRleCxcclxuXHRcdFx0XHRcdHNjcm9sbFN0YXJ0UG9zaXRpb246IHZpZXdwb3J0LnNjcm9sbFN0YXJ0UG9zaXRpb24sXHJcblx0XHRcdFx0XHRzY3JvbGxFbmRQb3NpdGlvbjogdmlld3BvcnQuc2Nyb2xsRW5kUG9zaXRpb24sXHJcblx0XHRcdFx0XHRzY3JvbGxEaXJlY3Rpb246IHNjcm9sbERpcmVjdGlvbixcclxuXHRcdFx0XHRcdHN0YXJ0SW5kZXhXaXRoQnVmZmVyOiB2aWV3cG9ydC5zdGFydEluZGV4V2l0aEJ1ZmZlcixcclxuXHRcdFx0XHRcdGVuZEluZGV4V2l0aEJ1ZmZlcjogdmlld3BvcnQuZW5kSW5kZXhXaXRoQnVmZmVyLFxyXG5cdFx0XHRcdFx0bWF4U2Nyb2xsUG9zaXRpb246IHZpZXdwb3J0Lm1heFNjcm9sbFBvc2l0aW9uLFxyXG5cdFx0XHRcdH0gOiB1bmRlZmluZWQ7XHJcblxyXG5cclxuXHRcdFx0XHRpZiAoc3RhcnRDaGFuZ2VkIHx8IGVuZENoYW5nZWQgfHwgc2Nyb2xsUG9zaXRpb25DaGFuZ2VkKSB7XHJcblx0XHRcdFx0XHRjb25zdCBoYW5kbGVDaGFuZ2VkID0gKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHQvLyB1cGRhdGUgdGhlIHNjcm9sbCBsaXN0IHRvIHRyaWdnZXIgcmUtcmVuZGVyIG9mIGNvbXBvbmVudHMgaW4gdmlld3BvcnRcclxuXHRcdFx0XHRcdFx0dGhpcy52aWV3UG9ydEl0ZW1zID0gdmlld3BvcnQuc3RhcnRJbmRleFdpdGhCdWZmZXIgPj0gMCAmJiB2aWV3cG9ydC5lbmRJbmRleFdpdGhCdWZmZXIgPj0gMCA/IHRoaXMuaXRlbXMuc2xpY2Uodmlld3BvcnQuc3RhcnRJbmRleFdpdGhCdWZmZXIsIHZpZXdwb3J0LmVuZEluZGV4V2l0aEJ1ZmZlciArIDEpIDogW107XHJcblx0XHRcdFx0XHRcdHRoaXMudnNVcGRhdGUuZW1pdCh0aGlzLnZpZXdQb3J0SXRlbXMpO1xyXG5cclxuXHRcdFx0XHRcdFx0aWYgKHN0YXJ0Q2hhbmdlZCkge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMudnNTdGFydC5lbWl0KGNoYW5nZUV2ZW50QXJnKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdFx0aWYgKGVuZENoYW5nZWQpIHtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLnZzRW5kLmVtaXQoY2hhbmdlRXZlbnRBcmcpO1xyXG5cdFx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0XHRpZiAoc3RhcnRDaGFuZ2VkIHx8IGVuZENoYW5nZWQpIHtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLmNoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMudnNDaGFuZ2UuZW1pdChjaGFuZ2VFdmVudEFyZyk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHRcdGlmIChtYXhSdW5UaW1lcyA+IDApIHtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLnJlZnJlc2hfaW50ZXJuYWwoZmFsc2UsIHJlZnJlc2hDb21wbGV0ZWRDYWxsYmFjaywgbWF4UnVuVGltZXMgLSAxKTtcclxuXHRcdFx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHRcdGlmIChyZWZyZXNoQ29tcGxldGVkQ2FsbGJhY2spIHtcclxuXHRcdFx0XHRcdFx0XHRyZWZyZXNoQ29tcGxldGVkQ2FsbGJhY2soKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fTtcclxuXHJcblxyXG5cdFx0XHRcdFx0aWYgKHRoaXMuZXhlY3V0ZVJlZnJlc2hPdXRzaWRlQW5ndWxhclpvbmUpIHtcclxuXHRcdFx0XHRcdFx0aGFuZGxlQ2hhbmdlZCgpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0ZWxzZSB7XHJcblx0XHRcdFx0XHRcdHRoaXMuem9uZS5ydW4oaGFuZGxlQ2hhbmdlZCk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdGlmIChtYXhSdW5UaW1lcyA+IDAgJiYgKHNjcm9sbExlbmd0aENoYW5nZWQgfHwgcGFkZGluZ0NoYW5nZWQpKSB7XHJcblx0XHRcdFx0XHRcdHRoaXMucmVmcmVzaF9pbnRlcm5hbChmYWxzZSwgcmVmcmVzaENvbXBsZXRlZENhbGxiYWNrLCBtYXhSdW5UaW1lcyAtIDEpO1xyXG5cdFx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0aWYgKHJlZnJlc2hDb21wbGV0ZWRDYWxsYmFjaykge1xyXG5cdFx0XHRcdFx0XHRyZWZyZXNoQ29tcGxldGVkQ2FsbGJhY2soKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHRwcm90ZWN0ZWQgZ2V0U2Nyb2xsRWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XHJcblx0XHRyZXR1cm4gdGhpcy5wYXJlbnRTY3JvbGwgaW5zdGFuY2VvZiBXaW5kb3cgPyBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCB8fCBkb2N1bWVudC5ib2R5IDogdGhpcy5wYXJlbnRTY3JvbGwgfHwgdGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQ7XHJcblx0fVxyXG5cclxuXHRwcm90ZWN0ZWQgYWRkU2Nyb2xsRXZlbnRIYW5kbGVycygpOiB2b2lkIHtcclxuXHRcdGlmICh0aGlzLmlzQW5ndWxhclVuaXZlcnNhbFNTUikge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0Y29uc3Qgc2Nyb2xsRWxlbWVudCA9IHRoaXMuZ2V0U2Nyb2xsRWxlbWVudCgpO1xyXG5cclxuXHRcdHRoaXMucmVtb3ZlU2Nyb2xsRXZlbnRIYW5kbGVycygpO1xyXG5cclxuXHRcdHRoaXMuem9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XHJcblx0XHRcdGlmICh0aGlzLnBhcmVudFNjcm9sbCBpbnN0YW5jZW9mIFdpbmRvdykge1xyXG5cdFx0XHRcdHRoaXMuZGlzcG9zZVNjcm9sbEhhbmRsZXIgPSB0aGlzLnJlbmRlcmVyLmxpc3Rlbignd2luZG93JywgJ3Njcm9sbCcsIHRoaXMub25TY3JvbGwpO1xyXG5cdFx0XHRcdHRoaXMuZGlzcG9zZVJlc2l6ZUhhbmRsZXIgPSB0aGlzLnJlbmRlcmVyLmxpc3Rlbignd2luZG93JywgJ3Jlc2l6ZScsIHRoaXMub25TY3JvbGwpO1xyXG5cdFx0XHR9XHJcblx0XHRcdGVsc2Uge1xyXG5cdFx0XHRcdHRoaXMuZGlzcG9zZVNjcm9sbEhhbmRsZXIgPSB0aGlzLnJlbmRlcmVyLmxpc3RlbihzY3JvbGxFbGVtZW50LCAnc2Nyb2xsJywgdGhpcy5vblNjcm9sbCk7XHJcblx0XHRcdFx0aWYgKHRoaXMuX2NoZWNrUmVzaXplSW50ZXJ2YWwgPiAwKSB7XHJcblx0XHRcdFx0XHR0aGlzLmNoZWNrU2Nyb2xsRWxlbWVudFJlc2l6ZWRUaW1lciA9IDxhbnk+c2V0SW50ZXJ2YWwoKCkgPT4geyB0aGlzLmNoZWNrU2Nyb2xsRWxlbWVudFJlc2l6ZWQoKTsgfSwgdGhpcy5fY2hlY2tSZXNpemVJbnRlcnZhbCk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG5cdHByb3RlY3RlZCByZW1vdmVTY3JvbGxFdmVudEhhbmRsZXJzKCk6IHZvaWQge1xyXG5cdFx0aWYgKHRoaXMuY2hlY2tTY3JvbGxFbGVtZW50UmVzaXplZFRpbWVyKSB7XHJcblx0XHRcdGNsZWFySW50ZXJ2YWwodGhpcy5jaGVja1Njcm9sbEVsZW1lbnRSZXNpemVkVGltZXIpO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICh0aGlzLmRpc3Bvc2VTY3JvbGxIYW5kbGVyKSB7XHJcblx0XHRcdHRoaXMuZGlzcG9zZVNjcm9sbEhhbmRsZXIoKTtcclxuXHRcdFx0dGhpcy5kaXNwb3NlU2Nyb2xsSGFuZGxlciA9IHVuZGVmaW5lZDtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAodGhpcy5kaXNwb3NlUmVzaXplSGFuZGxlcikge1xyXG5cdFx0XHR0aGlzLmRpc3Bvc2VSZXNpemVIYW5kbGVyKCk7XHJcblx0XHRcdHRoaXMuZGlzcG9zZVJlc2l6ZUhhbmRsZXIgPSB1bmRlZmluZWQ7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRwcm90ZWN0ZWQgZ2V0RWxlbWVudHNPZmZzZXQoKTogbnVtYmVyIHtcclxuXHRcdGlmICh0aGlzLmlzQW5ndWxhclVuaXZlcnNhbFNTUikge1xyXG5cdFx0XHRyZXR1cm4gMDtcclxuXHRcdH1cclxuXHJcblx0XHRsZXQgb2Zmc2V0ID0gMDtcclxuXHJcblx0XHRpZiAodGhpcy5jb250YWluZXJFbGVtZW50UmVmICYmIHRoaXMuY29udGFpbmVyRWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KSB7XHJcblx0XHRcdG9mZnNldCArPSB0aGlzLmNvbnRhaW5lckVsZW1lbnRSZWYubmF0aXZlRWxlbWVudFt0aGlzLl9vZmZzZXRUeXBlXTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAodGhpcy5wYXJlbnRTY3JvbGwpIHtcclxuXHRcdFx0Y29uc3Qgc2Nyb2xsRWxlbWVudCA9IHRoaXMuZ2V0U2Nyb2xsRWxlbWVudCgpO1xyXG5cdFx0XHRjb25zdCBlbGVtZW50Q2xpZW50UmVjdCA9IHRoaXMuZ2V0RWxlbWVudFNpemUodGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQpO1xyXG5cdFx0XHRjb25zdCBzY3JvbGxDbGllbnRSZWN0ID0gdGhpcy5nZXRFbGVtZW50U2l6ZShzY3JvbGxFbGVtZW50KTtcclxuXHRcdFx0aWYgKHRoaXMuaG9yaXpvbnRhbCkge1xyXG5cdFx0XHRcdG9mZnNldCArPSBlbGVtZW50Q2xpZW50UmVjdC5sZWZ0IC0gc2Nyb2xsQ2xpZW50UmVjdC5sZWZ0O1xyXG5cdFx0XHR9XHJcblx0XHRcdGVsc2Uge1xyXG5cdFx0XHRcdG9mZnNldCArPSBlbGVtZW50Q2xpZW50UmVjdC50b3AgLSBzY3JvbGxDbGllbnRSZWN0LnRvcDtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aWYgKCEodGhpcy5wYXJlbnRTY3JvbGwgaW5zdGFuY2VvZiBXaW5kb3cpKSB7XHJcblx0XHRcdFx0b2Zmc2V0ICs9IHNjcm9sbEVsZW1lbnRbdGhpcy5fc2Nyb2xsVHlwZV07XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gb2Zmc2V0O1xyXG5cdH1cclxuXHJcblx0cHJvdGVjdGVkIGNvdW50SXRlbXNQZXJXcmFwR3JvdXAoKTogbnVtYmVyIHtcclxuXHRcdGlmICh0aGlzLmlzQW5ndWxhclVuaXZlcnNhbFNTUikge1xyXG5cdFx0XHRyZXR1cm4gTWF0aC5yb3VuZCh0aGlzLmhvcml6b250YWwgPyB0aGlzLnNzclZpZXdwb3J0SGVpZ2h0IC8gdGhpcy5zc3JDaGlsZEhlaWdodCA6IHRoaXMuc3NyVmlld3BvcnRXaWR0aCAvIHRoaXMuc3NyQ2hpbGRXaWR0aCk7XHJcblx0XHR9XHJcblxyXG5cdFx0Y29uc3QgcHJvcGVydHlOYW1lID0gdGhpcy5ob3Jpem9udGFsID8gJ29mZnNldExlZnQnIDogJ29mZnNldFRvcCc7XHJcblx0XHRjb25zdCBjaGlsZHJlbiA9IHRoaXMuZ2V0Q29udGVudCgpLmNoaWxkcmVuO1xyXG5cclxuXHRcdGNvbnN0IGNoaWxkcmVuTGVuZ3RoID0gY2hpbGRyZW4gPyBjaGlsZHJlbi5sZW5ndGggOiAwO1xyXG5cdFx0aWYgKGNoaWxkcmVuTGVuZ3RoID09PSAwKSB7XHJcblx0XHRcdHJldHVybiAxO1xyXG5cdFx0fVxyXG5cclxuXHRcdGNvbnN0IGZpcnN0T2Zmc2V0ID0gY2hpbGRyZW5bMF1bcHJvcGVydHlOYW1lXTtcclxuXHRcdGxldCByZXN1bHQgPSAxO1xyXG5cdFx0d2hpbGUgKHJlc3VsdCA8IGNoaWxkcmVuTGVuZ3RoICYmIGZpcnN0T2Zmc2V0ID09PSBjaGlsZHJlbltyZXN1bHRdW3Byb3BlcnR5TmFtZV0pIHtcclxuXHRcdFx0KytyZXN1bHQ7XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHByb3RlY3RlZCBnZXRTY3JvbGxTdGFydFBvc2l0aW9uKCk6IG51bWJlciB7XHJcblx0XHRsZXQgd2luZG93U2Nyb2xsVmFsdWUgPSB1bmRlZmluZWQ7XHJcblx0XHRpZiAodGhpcy5wYXJlbnRTY3JvbGwgaW5zdGFuY2VvZiBXaW5kb3cpIHtcclxuXHRcdFx0d2luZG93U2Nyb2xsVmFsdWUgPSB3aW5kb3dbdGhpcy5fcGFnZU9mZnNldFR5cGVdO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB3aW5kb3dTY3JvbGxWYWx1ZSB8fCB0aGlzLmdldFNjcm9sbEVsZW1lbnQoKVt0aGlzLl9zY3JvbGxUeXBlXSB8fCAwO1xyXG5cdH1cclxuXHJcblx0cHJvdGVjdGVkIG1pbk1lYXN1cmVkQ2hpbGRXaWR0aDogbnVtYmVyO1xyXG5cdHByb3RlY3RlZCBtaW5NZWFzdXJlZENoaWxkSGVpZ2h0OiBudW1iZXI7XHJcblxyXG5cdHByb3RlY3RlZCB3cmFwR3JvdXBEaW1lbnNpb25zOiBXcmFwR3JvdXBEaW1lbnNpb25zO1xyXG5cclxuXHRwcm90ZWN0ZWQgcmVzZXRXcmFwR3JvdXBEaW1lbnNpb25zKCk6IHZvaWQge1xyXG5cdFx0Y29uc3Qgb2xkV3JhcEdyb3VwRGltZW5zaW9ucyA9IHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucztcclxuXHRcdHRoaXMuaW52YWxpZGF0ZUFsbENhY2hlZE1lYXN1cmVtZW50cygpO1xyXG5cclxuXHRcdGlmICghdGhpcy5lbmFibGVVbmVxdWFsQ2hpbGRyZW5TaXplcyB8fCAhb2xkV3JhcEdyb3VwRGltZW5zaW9ucyB8fCBvbGRXcmFwR3JvdXBEaW1lbnNpb25zLm51bWJlck9mS25vd25XcmFwR3JvdXBDaGlsZFNpemVzID09PSAwKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHRjb25zdCBpdGVtc1BlcldyYXBHcm91cDogbnVtYmVyID0gdGhpcy5jb3VudEl0ZW1zUGVyV3JhcEdyb3VwKCk7XHJcblx0XHRmb3IgKGxldCB3cmFwR3JvdXBJbmRleCA9IDA7IHdyYXBHcm91cEluZGV4IDwgb2xkV3JhcEdyb3VwRGltZW5zaW9ucy5tYXhDaGlsZFNpemVQZXJXcmFwR3JvdXAubGVuZ3RoOyArK3dyYXBHcm91cEluZGV4KSB7XHJcblx0XHRcdGNvbnN0IG9sZFdyYXBHcm91cERpbWVuc2lvbjogV3JhcEdyb3VwRGltZW5zaW9uID0gb2xkV3JhcEdyb3VwRGltZW5zaW9ucy5tYXhDaGlsZFNpemVQZXJXcmFwR3JvdXBbd3JhcEdyb3VwSW5kZXhdO1xyXG5cdFx0XHRpZiAoIW9sZFdyYXBHcm91cERpbWVuc2lvbiB8fCAhb2xkV3JhcEdyb3VwRGltZW5zaW9uLml0ZW1zIHx8ICFvbGRXcmFwR3JvdXBEaW1lbnNpb24uaXRlbXMubGVuZ3RoKSB7XHJcblx0XHRcdFx0Y29udGludWU7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGlmIChvbGRXcmFwR3JvdXBEaW1lbnNpb24uaXRlbXMubGVuZ3RoICE9PSBpdGVtc1BlcldyYXBHcm91cCkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0bGV0IGl0ZW1zQ2hhbmdlZCA9IGZhbHNlO1xyXG5cdFx0XHRjb25zdCBhcnJheVN0YXJ0SW5kZXggPSBpdGVtc1BlcldyYXBHcm91cCAqIHdyYXBHcm91cEluZGV4O1xyXG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGl0ZW1zUGVyV3JhcEdyb3VwOyArK2kpIHtcclxuXHRcdFx0XHRpZiAoIXRoaXMuY29tcGFyZUl0ZW1zKG9sZFdyYXBHcm91cERpbWVuc2lvbi5pdGVtc1tpXSwgdGhpcy5pdGVtc1thcnJheVN0YXJ0SW5kZXggKyBpXSkpIHtcclxuXHRcdFx0XHRcdGl0ZW1zQ2hhbmdlZCA9IHRydWU7XHJcblx0XHRcdFx0XHRicmVhaztcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGlmICghaXRlbXNDaGFuZ2VkKSB7XHJcblx0XHRcdFx0Kyt0aGlzLndyYXBHcm91cERpbWVuc2lvbnMubnVtYmVyT2ZLbm93bldyYXBHcm91cENoaWxkU2l6ZXM7XHJcblx0XHRcdFx0dGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLnN1bU9mS25vd25XcmFwR3JvdXBDaGlsZFdpZHRocyArPSBvbGRXcmFwR3JvdXBEaW1lbnNpb24uY2hpbGRXaWR0aCB8fCAwO1xyXG5cdFx0XHRcdHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5zdW1PZktub3duV3JhcEdyb3VwQ2hpbGRIZWlnaHRzICs9IG9sZFdyYXBHcm91cERpbWVuc2lvbi5jaGlsZEhlaWdodCB8fCAwO1xyXG5cdFx0XHRcdHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5tYXhDaGlsZFNpemVQZXJXcmFwR3JvdXBbd3JhcEdyb3VwSW5kZXhdID0gb2xkV3JhcEdyb3VwRGltZW5zaW9uO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRwcm90ZWN0ZWQgY2FsY3VsYXRlRGltZW5zaW9ucygpOiBJRGltZW5zaW9ucyB7XHJcblx0XHRjb25zdCBzY3JvbGxFbGVtZW50ID0gdGhpcy5nZXRTY3JvbGxFbGVtZW50KCk7XHJcblxyXG5cdFx0Y29uc3QgbWF4Q2FsY3VsYXRlZFNjcm9sbEJhclNpemUgPSAyNTsgLy8gTm90ZTogRm9ybXVsYSB0byBhdXRvLWNhbGN1bGF0ZSBkb2Vzbid0IHdvcmsgZm9yIFBhcmVudFNjcm9sbCwgc28gd2UgZGVmYXVsdCB0byB0aGlzIGlmIG5vdCBzZXQgYnkgY29uc3VtaW5nIGFwcGxpY2F0aW9uXHJcblx0XHR0aGlzLmNhbGN1bGF0ZWRTY3JvbGxiYXJIZWlnaHQgPSBNYXRoLm1heChNYXRoLm1pbihzY3JvbGxFbGVtZW50Lm9mZnNldEhlaWdodCAtIHNjcm9sbEVsZW1lbnQuY2xpZW50SGVpZ2h0LCBtYXhDYWxjdWxhdGVkU2Nyb2xsQmFyU2l6ZSksIHRoaXMuY2FsY3VsYXRlZFNjcm9sbGJhckhlaWdodCk7XHJcblx0XHR0aGlzLmNhbGN1bGF0ZWRTY3JvbGxiYXJXaWR0aCA9IE1hdGgubWF4KE1hdGgubWluKHNjcm9sbEVsZW1lbnQub2Zmc2V0V2lkdGggLSBzY3JvbGxFbGVtZW50LmNsaWVudFdpZHRoLCBtYXhDYWxjdWxhdGVkU2Nyb2xsQmFyU2l6ZSksIHRoaXMuY2FsY3VsYXRlZFNjcm9sbGJhcldpZHRoKTtcclxuXHJcblx0XHRsZXQgdmlld3BvcnRXaWR0aCA9IHNjcm9sbEVsZW1lbnQub2Zmc2V0V2lkdGggLSAodGhpcy5zY3JvbGxiYXJXaWR0aCB8fCB0aGlzLmNhbGN1bGF0ZWRTY3JvbGxiYXJXaWR0aCB8fCAodGhpcy5ob3Jpem9udGFsID8gMCA6IG1heENhbGN1bGF0ZWRTY3JvbGxCYXJTaXplKSk7XHJcblx0XHRsZXQgdmlld3BvcnRIZWlnaHQgPSBzY3JvbGxFbGVtZW50Lm9mZnNldEhlaWdodCAtICh0aGlzLnNjcm9sbGJhckhlaWdodCB8fCB0aGlzLmNhbGN1bGF0ZWRTY3JvbGxiYXJIZWlnaHQgfHwgKHRoaXMuaG9yaXpvbnRhbCA/IG1heENhbGN1bGF0ZWRTY3JvbGxCYXJTaXplIDogMCkpO1xyXG5cclxuXHRcdGNvbnN0IGNvbnRlbnQgPSB0aGlzLmdldENvbnRlbnQoKTtcclxuXHJcblx0XHRjb25zdCBpdGVtc1BlcldyYXBHcm91cCA9IHRoaXMuY291bnRJdGVtc1BlcldyYXBHcm91cCgpO1xyXG5cdFx0bGV0IHdyYXBHcm91cHNQZXJQYWdlO1xyXG5cclxuXHRcdGxldCBkZWZhdWx0Q2hpbGRXaWR0aDtcclxuXHRcdGxldCBkZWZhdWx0Q2hpbGRIZWlnaHQ7XHJcblxyXG5cdFx0aWYgKHRoaXMuaXNBbmd1bGFyVW5pdmVyc2FsU1NSKSB7XHJcblx0XHRcdHZpZXdwb3J0V2lkdGggPSB0aGlzLnNzclZpZXdwb3J0V2lkdGg7XHJcblx0XHRcdHZpZXdwb3J0SGVpZ2h0ID0gdGhpcy5zc3JWaWV3cG9ydEhlaWdodDtcclxuXHRcdFx0ZGVmYXVsdENoaWxkV2lkdGggPSB0aGlzLnNzckNoaWxkV2lkdGg7XHJcblx0XHRcdGRlZmF1bHRDaGlsZEhlaWdodCA9IHRoaXMuc3NyQ2hpbGRIZWlnaHQ7XHJcblx0XHRcdGNvbnN0IGl0ZW1zUGVyUm93ID0gTWF0aC5tYXgoTWF0aC5jZWlsKHZpZXdwb3J0V2lkdGggLyBkZWZhdWx0Q2hpbGRXaWR0aCksIDEpO1xyXG5cdFx0XHRjb25zdCBpdGVtc1BlckNvbCA9IE1hdGgubWF4KE1hdGguY2VpbCh2aWV3cG9ydEhlaWdodCAvIGRlZmF1bHRDaGlsZEhlaWdodCksIDEpO1xyXG5cdFx0XHR3cmFwR3JvdXBzUGVyUGFnZSA9IHRoaXMuaG9yaXpvbnRhbCA/IGl0ZW1zUGVyUm93IDogaXRlbXNQZXJDb2w7XHJcblx0XHR9XHJcblx0XHRlbHNlIGlmICghdGhpcy5lbmFibGVVbmVxdWFsQ2hpbGRyZW5TaXplcykge1xyXG5cdFx0XHRpZiAoY29udGVudC5jaGlsZHJlbi5sZW5ndGggPiAwKSB7XHJcblx0XHRcdFx0aWYgKCF0aGlzLmNoaWxkV2lkdGggfHwgIXRoaXMuY2hpbGRIZWlnaHQpIHtcclxuXHRcdFx0XHRcdGlmICghdGhpcy5taW5NZWFzdXJlZENoaWxkV2lkdGggJiYgdmlld3BvcnRXaWR0aCA+IDApIHtcclxuXHRcdFx0XHRcdFx0dGhpcy5taW5NZWFzdXJlZENoaWxkV2lkdGggPSB2aWV3cG9ydFdpZHRoO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0aWYgKCF0aGlzLm1pbk1lYXN1cmVkQ2hpbGRIZWlnaHQgJiYgdmlld3BvcnRIZWlnaHQgPiAwKSB7XHJcblx0XHRcdFx0XHRcdHRoaXMubWluTWVhc3VyZWRDaGlsZEhlaWdodCA9IHZpZXdwb3J0SGVpZ2h0O1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Y29uc3QgY2hpbGQgPSBjb250ZW50LmNoaWxkcmVuWzBdO1xyXG5cdFx0XHRcdGNvbnN0IGNsaWVudFJlY3QgPSB0aGlzLmdldEVsZW1lbnRTaXplKGNoaWxkKTtcclxuXHRcdFx0XHR0aGlzLm1pbk1lYXN1cmVkQ2hpbGRXaWR0aCA9IE1hdGgubWluKHRoaXMubWluTWVhc3VyZWRDaGlsZFdpZHRoLCBjbGllbnRSZWN0LndpZHRoKTtcclxuXHRcdFx0XHR0aGlzLm1pbk1lYXN1cmVkQ2hpbGRIZWlnaHQgPSBNYXRoLm1pbih0aGlzLm1pbk1lYXN1cmVkQ2hpbGRIZWlnaHQsIGNsaWVudFJlY3QuaGVpZ2h0KTtcclxuXHJcblx0XHRcdFx0Ly8gQWRkZWQgZm9yIGdldHRpbmcgdGhlIGNoaWxkIGhlaWdodCAoZm9yIGNhcmQgdmlldywgcmV0dXJuIGFsbCB0aGUgY2xpZW50UmVjdCBvYmplY3QpLlxyXG5cdFx0XHRcdC8vIGlmICh0aGlzLl9sYXN0Q2hpbGRSZWN0ID09PSBudWxsIHx8XHJcblx0XHRcdFx0Ly8gXHQoY2xpZW50UmVjdD8uaGVpZ2h0ICE9PSAwICYmIChcclxuXHRcdFx0XHQvLyBcdFx0TWF0aC5yb3VuZCh0aGlzLl9sYXN0Q2hpbGRSZWN0Py5oZWlnaHQpICE9PSBNYXRoLnJvdW5kKGNsaWVudFJlY3Q/LmhlaWdodCkgfHwgXHJcblx0XHRcdFx0Ly8gXHRcdE1hdGgucm91bmQodGhpcy5fbGFzdENoaWxkUmVjdD8ud2lkdGgpICE9PSBNYXRoLnJvdW5kKGNsaWVudFJlY3Q/LndpZHRoKSlcclxuXHRcdFx0XHQvLyBcdCkpIHtcclxuXHRcdFx0XHQvLyBcdHRoaXMuX2xhc3RDaGlsZFJlY3QgPSBjbGllbnRSZWN0O1xyXG5cdFx0XHRcdC8vIFx0dGhpcy52c0NoaWxkUmVjdENoYW5nZS5lbWl0KGNsaWVudFJlY3QpO1xyXG5cdFx0XHRcdC8vIH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0ZGVmYXVsdENoaWxkV2lkdGggPSB0aGlzLmNoaWxkV2lkdGggfHwgdGhpcy5taW5NZWFzdXJlZENoaWxkV2lkdGggfHwgdmlld3BvcnRXaWR0aDtcclxuXHRcdFx0ZGVmYXVsdENoaWxkSGVpZ2h0ID0gdGhpcy5jaGlsZEhlaWdodCB8fCB0aGlzLm1pbk1lYXN1cmVkQ2hpbGRIZWlnaHQgfHwgdmlld3BvcnRIZWlnaHQ7XHJcblx0XHRcdGNvbnN0IGl0ZW1zUGVyUm93ID0gTWF0aC5tYXgoTWF0aC5jZWlsKHZpZXdwb3J0V2lkdGggLyBkZWZhdWx0Q2hpbGRXaWR0aCksIDEpO1xyXG5cdFx0XHRjb25zdCBpdGVtc1BlckNvbCA9IE1hdGgubWF4KE1hdGguY2VpbCh2aWV3cG9ydEhlaWdodCAvIGRlZmF1bHRDaGlsZEhlaWdodCksIDEpO1xyXG5cdFx0XHR3cmFwR3JvdXBzUGVyUGFnZSA9IHRoaXMuaG9yaXpvbnRhbCA/IGl0ZW1zUGVyUm93IDogaXRlbXNQZXJDb2w7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRsZXQgc2Nyb2xsT2Zmc2V0ID0gc2Nyb2xsRWxlbWVudFt0aGlzLl9zY3JvbGxUeXBlXSAtICh0aGlzLnByZXZpb3VzVmlld1BvcnQgPyB0aGlzLnByZXZpb3VzVmlld1BvcnQucGFkZGluZyA6IDApO1xyXG5cclxuXHRcdFx0bGV0IGFycmF5U3RhcnRJbmRleCA9IHRoaXMucHJldmlvdXNWaWV3UG9ydC5zdGFydEluZGV4V2l0aEJ1ZmZlciB8fCAwO1xyXG5cdFx0XHRsZXQgd3JhcEdyb3VwSW5kZXggPSBNYXRoLmNlaWwoYXJyYXlTdGFydEluZGV4IC8gaXRlbXNQZXJXcmFwR3JvdXApO1xyXG5cclxuXHRcdFx0bGV0IG1heFdpZHRoRm9yV3JhcEdyb3VwID0gMDtcclxuXHRcdFx0bGV0IG1heEhlaWdodEZvcldyYXBHcm91cCA9IDA7XHJcblx0XHRcdGxldCBzdW1PZlZpc2libGVNYXhXaWR0aHMgPSAwO1xyXG5cdFx0XHRsZXQgc3VtT2ZWaXNpYmxlTWF4SGVpZ2h0cyA9IDA7XHJcblx0XHRcdHdyYXBHcm91cHNQZXJQYWdlID0gMDtcclxuXHJcblx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgY29udGVudC5jaGlsZHJlbi5sZW5ndGg7ICsraSkge1xyXG5cdFx0XHRcdCsrYXJyYXlTdGFydEluZGV4O1xyXG5cdFx0XHRcdGNvbnN0IGNoaWxkID0gY29udGVudC5jaGlsZHJlbltpXTtcclxuXHRcdFx0XHRjb25zdCBjbGllbnRSZWN0ID0gdGhpcy5nZXRFbGVtZW50U2l6ZShjaGlsZCk7XHJcblxyXG5cdFx0XHRcdG1heFdpZHRoRm9yV3JhcEdyb3VwID0gTWF0aC5tYXgobWF4V2lkdGhGb3JXcmFwR3JvdXAsIGNsaWVudFJlY3Qud2lkdGgpO1xyXG5cdFx0XHRcdG1heEhlaWdodEZvcldyYXBHcm91cCA9IE1hdGgubWF4KG1heEhlaWdodEZvcldyYXBHcm91cCwgY2xpZW50UmVjdC5oZWlnaHQpO1xyXG5cclxuXHRcdFx0XHRpZiAoYXJyYXlTdGFydEluZGV4ICUgaXRlbXNQZXJXcmFwR3JvdXAgPT09IDApIHtcclxuXHRcdFx0XHRcdGNvbnN0IG9sZFZhbHVlID0gdGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLm1heENoaWxkU2l6ZVBlcldyYXBHcm91cFt3cmFwR3JvdXBJbmRleF07XHJcblx0XHRcdFx0XHRpZiAob2xkVmFsdWUpIHtcclxuXHRcdFx0XHRcdFx0LS10aGlzLndyYXBHcm91cERpbWVuc2lvbnMubnVtYmVyT2ZLbm93bldyYXBHcm91cENoaWxkU2l6ZXM7XHJcblx0XHRcdFx0XHRcdHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5zdW1PZktub3duV3JhcEdyb3VwQ2hpbGRXaWR0aHMgLT0gb2xkVmFsdWUuY2hpbGRXaWR0aCB8fCAwO1xyXG5cdFx0XHRcdFx0XHR0aGlzLndyYXBHcm91cERpbWVuc2lvbnMuc3VtT2ZLbm93bldyYXBHcm91cENoaWxkSGVpZ2h0cyAtPSBvbGRWYWx1ZS5jaGlsZEhlaWdodCB8fCAwO1xyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdCsrdGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLm51bWJlck9mS25vd25XcmFwR3JvdXBDaGlsZFNpemVzO1xyXG5cdFx0XHRcdFx0Y29uc3QgaXRlbXMgPSB0aGlzLml0ZW1zLnNsaWNlKGFycmF5U3RhcnRJbmRleCAtIGl0ZW1zUGVyV3JhcEdyb3VwLCBhcnJheVN0YXJ0SW5kZXgpO1xyXG5cdFx0XHRcdFx0dGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLm1heENoaWxkU2l6ZVBlcldyYXBHcm91cFt3cmFwR3JvdXBJbmRleF0gPSB7XHJcblx0XHRcdFx0XHRcdGNoaWxkV2lkdGg6IG1heFdpZHRoRm9yV3JhcEdyb3VwLFxyXG5cdFx0XHRcdFx0XHRjaGlsZEhlaWdodDogbWF4SGVpZ2h0Rm9yV3JhcEdyb3VwLFxyXG5cdFx0XHRcdFx0XHRpdGVtczogaXRlbXNcclxuXHRcdFx0XHRcdH07XHJcblx0XHRcdFx0XHR0aGlzLndyYXBHcm91cERpbWVuc2lvbnMuc3VtT2ZLbm93bldyYXBHcm91cENoaWxkV2lkdGhzICs9IG1heFdpZHRoRm9yV3JhcEdyb3VwO1xyXG5cdFx0XHRcdFx0dGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLnN1bU9mS25vd25XcmFwR3JvdXBDaGlsZEhlaWdodHMgKz0gbWF4SGVpZ2h0Rm9yV3JhcEdyb3VwO1xyXG5cclxuXHRcdFx0XHRcdGlmICh0aGlzLmhvcml6b250YWwpIHtcclxuXHRcdFx0XHRcdFx0bGV0IG1heFZpc2libGVXaWR0aEZvcldyYXBHcm91cCA9IE1hdGgubWluKG1heFdpZHRoRm9yV3JhcEdyb3VwLCBNYXRoLm1heCh2aWV3cG9ydFdpZHRoIC0gc3VtT2ZWaXNpYmxlTWF4V2lkdGhzLCAwKSk7XHJcblx0XHRcdFx0XHRcdGlmIChzY3JvbGxPZmZzZXQgPiAwKSB7XHJcblx0XHRcdFx0XHRcdFx0Y29uc3Qgc2Nyb2xsT2Zmc2V0VG9SZW1vdmUgPSBNYXRoLm1pbihzY3JvbGxPZmZzZXQsIG1heFZpc2libGVXaWR0aEZvcldyYXBHcm91cCk7XHJcblx0XHRcdFx0XHRcdFx0bWF4VmlzaWJsZVdpZHRoRm9yV3JhcEdyb3VwIC09IHNjcm9sbE9mZnNldFRvUmVtb3ZlO1xyXG5cdFx0XHRcdFx0XHRcdHNjcm9sbE9mZnNldCAtPSBzY3JvbGxPZmZzZXRUb1JlbW92ZTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdFx0c3VtT2ZWaXNpYmxlTWF4V2lkdGhzICs9IG1heFZpc2libGVXaWR0aEZvcldyYXBHcm91cDtcclxuXHRcdFx0XHRcdFx0aWYgKG1heFZpc2libGVXaWR0aEZvcldyYXBHcm91cCA+IDAgJiYgdmlld3BvcnRXaWR0aCA+PSBzdW1PZlZpc2libGVNYXhXaWR0aHMpIHtcclxuXHRcdFx0XHRcdFx0XHQrK3dyYXBHcm91cHNQZXJQYWdlO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRsZXQgbWF4VmlzaWJsZUhlaWdodEZvcldyYXBHcm91cCA9IE1hdGgubWluKG1heEhlaWdodEZvcldyYXBHcm91cCwgTWF0aC5tYXgodmlld3BvcnRIZWlnaHQgLSBzdW1PZlZpc2libGVNYXhIZWlnaHRzLCAwKSk7XHJcblx0XHRcdFx0XHRcdGlmIChzY3JvbGxPZmZzZXQgPiAwKSB7XHJcblx0XHRcdFx0XHRcdFx0Y29uc3Qgc2Nyb2xsT2Zmc2V0VG9SZW1vdmUgPSBNYXRoLm1pbihzY3JvbGxPZmZzZXQsIG1heFZpc2libGVIZWlnaHRGb3JXcmFwR3JvdXApO1xyXG5cdFx0XHRcdFx0XHRcdG1heFZpc2libGVIZWlnaHRGb3JXcmFwR3JvdXAgLT0gc2Nyb2xsT2Zmc2V0VG9SZW1vdmU7XHJcblx0XHRcdFx0XHRcdFx0c2Nyb2xsT2Zmc2V0IC09IHNjcm9sbE9mZnNldFRvUmVtb3ZlO1xyXG5cdFx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0XHRzdW1PZlZpc2libGVNYXhIZWlnaHRzICs9IG1heFZpc2libGVIZWlnaHRGb3JXcmFwR3JvdXA7XHJcblx0XHRcdFx0XHRcdGlmIChtYXhWaXNpYmxlSGVpZ2h0Rm9yV3JhcEdyb3VwID4gMCAmJiB2aWV3cG9ydEhlaWdodCA+PSBzdW1PZlZpc2libGVNYXhIZWlnaHRzKSB7XHJcblx0XHRcdFx0XHRcdFx0Kyt3cmFwR3JvdXBzUGVyUGFnZTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdCsrd3JhcEdyb3VwSW5kZXg7XHJcblxyXG5cdFx0XHRcdFx0bWF4V2lkdGhGb3JXcmFwR3JvdXAgPSAwO1xyXG5cdFx0XHRcdFx0bWF4SGVpZ2h0Rm9yV3JhcEdyb3VwID0gMDtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGNvbnN0IGF2ZXJhZ2VDaGlsZFdpZHRoID0gdGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLnN1bU9mS25vd25XcmFwR3JvdXBDaGlsZFdpZHRocyAvIHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5udW1iZXJPZktub3duV3JhcEdyb3VwQ2hpbGRTaXplcztcclxuXHRcdFx0Y29uc3QgYXZlcmFnZUNoaWxkSGVpZ2h0ID0gdGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLnN1bU9mS25vd25XcmFwR3JvdXBDaGlsZEhlaWdodHMgLyB0aGlzLndyYXBHcm91cERpbWVuc2lvbnMubnVtYmVyT2ZLbm93bldyYXBHcm91cENoaWxkU2l6ZXM7XHJcblx0XHRcdGRlZmF1bHRDaGlsZFdpZHRoID0gdGhpcy5jaGlsZFdpZHRoIHx8IGF2ZXJhZ2VDaGlsZFdpZHRoIHx8IHZpZXdwb3J0V2lkdGg7XHJcblx0XHRcdGRlZmF1bHRDaGlsZEhlaWdodCA9IHRoaXMuY2hpbGRIZWlnaHQgfHwgYXZlcmFnZUNoaWxkSGVpZ2h0IHx8IHZpZXdwb3J0SGVpZ2h0O1xyXG5cclxuXHRcdFx0aWYgKHRoaXMuaG9yaXpvbnRhbCkge1xyXG5cdFx0XHRcdGlmICh2aWV3cG9ydFdpZHRoID4gc3VtT2ZWaXNpYmxlTWF4V2lkdGhzKSB7XHJcblx0XHRcdFx0XHR3cmFwR3JvdXBzUGVyUGFnZSArPSBNYXRoLmNlaWwoKHZpZXdwb3J0V2lkdGggLSBzdW1PZlZpc2libGVNYXhXaWR0aHMpIC8gZGVmYXVsdENoaWxkV2lkdGgpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRpZiAodmlld3BvcnRIZWlnaHQgPiBzdW1PZlZpc2libGVNYXhIZWlnaHRzKSB7XHJcblx0XHRcdFx0XHR3cmFwR3JvdXBzUGVyUGFnZSArPSBNYXRoLmNlaWwoKHZpZXdwb3J0SGVpZ2h0IC0gc3VtT2ZWaXNpYmxlTWF4SGVpZ2h0cykgLyBkZWZhdWx0Q2hpbGRIZWlnaHQpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdGNvbnN0IGl0ZW1Db3VudCA9IHRoaXMuaXRlbXMubGVuZ3RoO1xyXG5cdFx0Y29uc3QgaXRlbXNQZXJQYWdlID0gaXRlbXNQZXJXcmFwR3JvdXAgKiB3cmFwR3JvdXBzUGVyUGFnZTtcclxuXHRcdGNvbnN0IHBhZ2VDb3VudF9mcmFjdGlvbmFsID0gaXRlbUNvdW50IC8gaXRlbXNQZXJQYWdlO1xyXG5cdFx0Y29uc3QgbnVtYmVyT2ZXcmFwR3JvdXBzID0gTWF0aC5jZWlsKGl0ZW1Db3VudCAvIGl0ZW1zUGVyV3JhcEdyb3VwKTtcclxuXHJcblx0XHRsZXQgc2Nyb2xsTGVuZ3RoID0gMDtcclxuXHJcblx0XHRjb25zdCBkZWZhdWx0U2Nyb2xsTGVuZ3RoUGVyV3JhcEdyb3VwID0gdGhpcy5ob3Jpem9udGFsID8gZGVmYXVsdENoaWxkV2lkdGggOiBkZWZhdWx0Q2hpbGRIZWlnaHQ7XHJcblx0XHRpZiAodGhpcy5lbmFibGVVbmVxdWFsQ2hpbGRyZW5TaXplcykge1xyXG5cdFx0XHRsZXQgbnVtVW5rbm93bkNoaWxkU2l6ZXMgPSAwO1xyXG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IG51bWJlck9mV3JhcEdyb3VwczsgKytpKSB7XHJcblx0XHRcdFx0Y29uc3QgY2hpbGRTaXplID0gdGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLm1heENoaWxkU2l6ZVBlcldyYXBHcm91cFtpXSAmJiB0aGlzLndyYXBHcm91cERpbWVuc2lvbnMubWF4Q2hpbGRTaXplUGVyV3JhcEdyb3VwW2ldW3RoaXMuX2NoaWxkU2Nyb2xsRGltXTtcclxuXHRcdFx0XHRpZiAoY2hpbGRTaXplKSB7XHJcblx0XHRcdFx0XHRzY3JvbGxMZW5ndGggKz0gY2hpbGRTaXplO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHQrK251bVVua25vd25DaGlsZFNpemVzO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0c2Nyb2xsTGVuZ3RoICs9IE1hdGgucm91bmQobnVtVW5rbm93bkNoaWxkU2l6ZXMgKiBkZWZhdWx0U2Nyb2xsTGVuZ3RoUGVyV3JhcEdyb3VwKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHNjcm9sbExlbmd0aCA9IG51bWJlck9mV3JhcEdyb3VwcyAqIGRlZmF1bHRTY3JvbGxMZW5ndGhQZXJXcmFwR3JvdXA7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKHRoaXMuaGVhZGVyRWxlbWVudFJlZikge1xyXG5cdFx0XHRzY3JvbGxMZW5ndGggKz0gdGhpcy5oZWFkZXJFbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuY2xpZW50SGVpZ2h0O1xyXG5cdFx0fVxyXG5cclxuXHRcdGNvbnN0IHZpZXdwb3J0TGVuZ3RoID0gdGhpcy5ob3Jpem9udGFsID8gdmlld3BvcnRXaWR0aCA6IHZpZXdwb3J0SGVpZ2h0O1xyXG5cdFx0Y29uc3QgbWF4U2Nyb2xsUG9zaXRpb24gPSBNYXRoLm1heChzY3JvbGxMZW5ndGggLSB2aWV3cG9ydExlbmd0aCwgMCk7XHJcblxyXG5cdFx0cmV0dXJuIHtcclxuXHRcdFx0Y2hpbGRIZWlnaHQ6IGRlZmF1bHRDaGlsZEhlaWdodCxcclxuXHRcdFx0Y2hpbGRXaWR0aDogZGVmYXVsdENoaWxkV2lkdGgsXHJcblx0XHRcdGl0ZW1Db3VudDogaXRlbUNvdW50LFxyXG5cdFx0XHRpdGVtc1BlclBhZ2U6IGl0ZW1zUGVyUGFnZSxcclxuXHRcdFx0aXRlbXNQZXJXcmFwR3JvdXA6IGl0ZW1zUGVyV3JhcEdyb3VwLFxyXG5cdFx0XHRtYXhTY3JvbGxQb3NpdGlvbjogbWF4U2Nyb2xsUG9zaXRpb24sXHJcblx0XHRcdHBhZ2VDb3VudF9mcmFjdGlvbmFsOiBwYWdlQ291bnRfZnJhY3Rpb25hbCxcclxuXHRcdFx0c2Nyb2xsTGVuZ3RoOiBzY3JvbGxMZW5ndGgsXHJcblx0XHRcdHZpZXdwb3J0TGVuZ3RoOiB2aWV3cG9ydExlbmd0aCxcclxuXHRcdFx0d3JhcEdyb3Vwc1BlclBhZ2U6IHdyYXBHcm91cHNQZXJQYWdlLFxyXG5cdFx0fTtcclxuXHR9XHJcblxyXG5cdHByb3RlY3RlZCBjYWNoZWRQYWdlU2l6ZSA9IDA7XHJcblx0cHJvdGVjdGVkIHByZXZpb3VzU2Nyb2xsTnVtYmVyRWxlbWVudHMgPSAwO1xyXG5cclxuXHRwcm90ZWN0ZWQgY2FsY3VsYXRlUGFkZGluZyhhcnJheVN0YXJ0SW5kZXhXaXRoQnVmZmVyOiBudW1iZXIsIGRpbWVuc2lvbnM6IElEaW1lbnNpb25zKTogbnVtYmVyIHtcclxuXHRcdGlmIChkaW1lbnNpb25zLml0ZW1Db3VudCA9PT0gMCkge1xyXG5cdFx0XHRyZXR1cm4gMDtcclxuXHRcdH1cclxuXHJcblx0XHRjb25zdCBkZWZhdWx0U2Nyb2xsTGVuZ3RoUGVyV3JhcEdyb3VwID0gZGltZW5zaW9uc1t0aGlzLl9jaGlsZFNjcm9sbERpbV07XHJcblx0XHRjb25zdCBzdGFydGluZ1dyYXBHcm91cEluZGV4ID0gTWF0aC5mbG9vcihhcnJheVN0YXJ0SW5kZXhXaXRoQnVmZmVyIC8gZGltZW5zaW9ucy5pdGVtc1BlcldyYXBHcm91cCkgfHwgMDtcclxuXHJcblx0XHRpZiAoIXRoaXMuZW5hYmxlVW5lcXVhbENoaWxkcmVuU2l6ZXMpIHtcclxuXHRcdFx0cmV0dXJuIGRlZmF1bHRTY3JvbGxMZW5ndGhQZXJXcmFwR3JvdXAgKiBzdGFydGluZ1dyYXBHcm91cEluZGV4O1xyXG5cdFx0fVxyXG5cclxuXHRcdGxldCBudW1Vbmtub3duQ2hpbGRTaXplcyA9IDA7XHJcblx0XHRsZXQgcmVzdWx0ID0gMDtcclxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgc3RhcnRpbmdXcmFwR3JvdXBJbmRleDsgKytpKSB7XHJcblx0XHRcdGNvbnN0IGNoaWxkU2l6ZSA9IHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5tYXhDaGlsZFNpemVQZXJXcmFwR3JvdXBbaV0gJiYgdGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLm1heENoaWxkU2l6ZVBlcldyYXBHcm91cFtpXVt0aGlzLl9jaGlsZFNjcm9sbERpbV07XHJcblx0XHRcdGlmIChjaGlsZFNpemUpIHtcclxuXHRcdFx0XHRyZXN1bHQgKz0gY2hpbGRTaXplO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdCsrbnVtVW5rbm93bkNoaWxkU2l6ZXM7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdHJlc3VsdCArPSBNYXRoLnJvdW5kKG51bVVua25vd25DaGlsZFNpemVzICogZGVmYXVsdFNjcm9sbExlbmd0aFBlcldyYXBHcm91cCk7XHJcblxyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHByb3RlY3RlZCBjYWxjdWxhdGVQYWdlSW5mbyhzY3JvbGxQb3NpdGlvbjogbnVtYmVyLCBkaW1lbnNpb25zOiBJRGltZW5zaW9ucyk6IElQYWdlSW5mbyB7XHJcblx0XHRsZXQgc2Nyb2xsUGVyY2VudGFnZSA9IDA7XHJcblx0XHRpZiAodGhpcy5lbmFibGVVbmVxdWFsQ2hpbGRyZW5TaXplcykge1xyXG5cdFx0XHRjb25zdCBudW1iZXJPZldyYXBHcm91cHMgPSBNYXRoLmNlaWwoZGltZW5zaW9ucy5pdGVtQ291bnQgLyBkaW1lbnNpb25zLml0ZW1zUGVyV3JhcEdyb3VwKTtcclxuXHRcdFx0bGV0IHRvdGFsU2Nyb2xsZWRMZW5ndGggPSAwO1xyXG5cdFx0XHRjb25zdCBkZWZhdWx0U2Nyb2xsTGVuZ3RoUGVyV3JhcEdyb3VwID0gZGltZW5zaW9uc1t0aGlzLl9jaGlsZFNjcm9sbERpbV07XHJcblx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgbnVtYmVyT2ZXcmFwR3JvdXBzOyArK2kpIHtcclxuXHRcdFx0XHRjb25zdCBjaGlsZFNpemUgPSB0aGlzLndyYXBHcm91cERpbWVuc2lvbnMubWF4Q2hpbGRTaXplUGVyV3JhcEdyb3VwW2ldICYmIHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5tYXhDaGlsZFNpemVQZXJXcmFwR3JvdXBbaV1bdGhpcy5fY2hpbGRTY3JvbGxEaW1dO1xyXG5cdFx0XHRcdGlmIChjaGlsZFNpemUpIHtcclxuXHRcdFx0XHRcdHRvdGFsU2Nyb2xsZWRMZW5ndGggKz0gY2hpbGRTaXplO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHR0b3RhbFNjcm9sbGVkTGVuZ3RoICs9IGRlZmF1bHRTY3JvbGxMZW5ndGhQZXJXcmFwR3JvdXA7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRpZiAoc2Nyb2xsUG9zaXRpb24gPCB0b3RhbFNjcm9sbGVkTGVuZ3RoKSB7XHJcblx0XHRcdFx0XHRzY3JvbGxQZXJjZW50YWdlID0gaSAvIG51bWJlck9mV3JhcEdyb3VwcztcclxuXHRcdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0c2Nyb2xsUGVyY2VudGFnZSA9IHNjcm9sbFBvc2l0aW9uIC8gZGltZW5zaW9ucy5zY3JvbGxMZW5ndGg7XHJcblx0XHR9XHJcblxyXG5cdFx0Y29uc3Qgc3RhcnRpbmdBcnJheUluZGV4X2ZyYWN0aW9uYWwgPSBNYXRoLm1pbihNYXRoLm1heChzY3JvbGxQZXJjZW50YWdlICogZGltZW5zaW9ucy5wYWdlQ291bnRfZnJhY3Rpb25hbCwgMCksIGRpbWVuc2lvbnMucGFnZUNvdW50X2ZyYWN0aW9uYWwpICogZGltZW5zaW9ucy5pdGVtc1BlclBhZ2U7XHJcblxyXG5cdFx0Y29uc3QgbWF4U3RhcnQgPSBkaW1lbnNpb25zLml0ZW1Db3VudCAtIGRpbWVuc2lvbnMuaXRlbXNQZXJQYWdlIC0gMTtcclxuXHRcdGxldCBhcnJheVN0YXJ0SW5kZXggPSBNYXRoLm1pbihNYXRoLmZsb29yKHN0YXJ0aW5nQXJyYXlJbmRleF9mcmFjdGlvbmFsKSwgbWF4U3RhcnQpO1xyXG5cdFx0YXJyYXlTdGFydEluZGV4IC09IGFycmF5U3RhcnRJbmRleCAlIGRpbWVuc2lvbnMuaXRlbXNQZXJXcmFwR3JvdXA7IC8vIHJvdW5kIGRvd24gdG8gc3RhcnQgb2Ygd3JhcEdyb3VwXHJcblxyXG5cdFx0aWYgKHRoaXMuc3RyaXBlZFRhYmxlKSB7XHJcblx0XHRcdGNvbnN0IGJ1ZmZlckJvdW5kYXJ5ID0gMiAqIGRpbWVuc2lvbnMuaXRlbXNQZXJXcmFwR3JvdXA7XHJcblx0XHRcdGlmIChhcnJheVN0YXJ0SW5kZXggJSBidWZmZXJCb3VuZGFyeSAhPT0gMCkge1xyXG5cdFx0XHRcdGFycmF5U3RhcnRJbmRleCA9IE1hdGgubWF4KGFycmF5U3RhcnRJbmRleCAtIGFycmF5U3RhcnRJbmRleCAlIGJ1ZmZlckJvdW5kYXJ5LCAwKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdGxldCBhcnJheUVuZEluZGV4ID0gTWF0aC5jZWlsKHN0YXJ0aW5nQXJyYXlJbmRleF9mcmFjdGlvbmFsKSArIGRpbWVuc2lvbnMuaXRlbXNQZXJQYWdlIC0gMTtcclxuXHRcdGNvbnN0IGVuZEluZGV4V2l0aGluV3JhcEdyb3VwID0gKGFycmF5RW5kSW5kZXggKyAxKSAlIGRpbWVuc2lvbnMuaXRlbXNQZXJXcmFwR3JvdXA7XHJcblx0XHRpZiAoZW5kSW5kZXhXaXRoaW5XcmFwR3JvdXAgPiAwKSB7XHJcblx0XHRcdGFycmF5RW5kSW5kZXggKz0gZGltZW5zaW9ucy5pdGVtc1BlcldyYXBHcm91cCAtIGVuZEluZGV4V2l0aGluV3JhcEdyb3VwOyAvLyByb3VuZCB1cCB0byBlbmQgb2Ygd3JhcEdyb3VwXHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKGlzTmFOKGFycmF5U3RhcnRJbmRleCkpIHtcclxuXHRcdFx0YXJyYXlTdGFydEluZGV4ID0gMDtcclxuXHRcdH1cclxuXHRcdGlmIChpc05hTihhcnJheUVuZEluZGV4KSkge1xyXG5cdFx0XHRhcnJheUVuZEluZGV4ID0gMDtcclxuXHRcdH1cclxuXHJcblx0XHRhcnJheVN0YXJ0SW5kZXggPSBNYXRoLm1pbihNYXRoLm1heChhcnJheVN0YXJ0SW5kZXgsIDApLCBkaW1lbnNpb25zLml0ZW1Db3VudCAtIDEpO1xyXG5cdFx0YXJyYXlFbmRJbmRleCA9IE1hdGgubWluKE1hdGgubWF4KGFycmF5RW5kSW5kZXgsIDApLCBkaW1lbnNpb25zLml0ZW1Db3VudCAtIDEpO1xyXG5cclxuXHRcdGNvbnN0IGJ1ZmZlclNpemUgPSB0aGlzLmJ1ZmZlckFtb3VudCAqIGRpbWVuc2lvbnMuaXRlbXNQZXJXcmFwR3JvdXA7XHJcblx0XHRjb25zdCBzdGFydEluZGV4V2l0aEJ1ZmZlciA9IE1hdGgubWluKE1hdGgubWF4KGFycmF5U3RhcnRJbmRleCAtIGJ1ZmZlclNpemUsIDApLCBkaW1lbnNpb25zLml0ZW1Db3VudCAtIDEpO1xyXG5cdFx0Y29uc3QgZW5kSW5kZXhXaXRoQnVmZmVyID0gTWF0aC5taW4oTWF0aC5tYXgoYXJyYXlFbmRJbmRleCArIGJ1ZmZlclNpemUsIDApLCBkaW1lbnNpb25zLml0ZW1Db3VudCAtIDEpO1xyXG5cclxuXHRcdHJldHVybiB7XHJcblx0XHRcdHN0YXJ0SW5kZXg6IGFycmF5U3RhcnRJbmRleCxcclxuXHRcdFx0ZW5kSW5kZXg6IGFycmF5RW5kSW5kZXgsXHJcblx0XHRcdHN0YXJ0SW5kZXhXaXRoQnVmZmVyOiBzdGFydEluZGV4V2l0aEJ1ZmZlcixcclxuXHRcdFx0ZW5kSW5kZXhXaXRoQnVmZmVyOiBlbmRJbmRleFdpdGhCdWZmZXIsXHJcblx0XHRcdHNjcm9sbFN0YXJ0UG9zaXRpb246IHNjcm9sbFBvc2l0aW9uLFxyXG5cdFx0XHRzY3JvbGxFbmRQb3NpdGlvbjogc2Nyb2xsUG9zaXRpb24gKyBkaW1lbnNpb25zLnZpZXdwb3J0TGVuZ3RoLFxyXG5cdFx0XHRtYXhTY3JvbGxQb3NpdGlvbjogZGltZW5zaW9ucy5tYXhTY3JvbGxQb3NpdGlvblxyXG5cdFx0fTtcclxuXHR9XHJcblxyXG5cdHByb3RlY3RlZCBjYWxjdWxhdGVWaWV3cG9ydCgpOiBJVmlld3BvcnQge1xyXG5cdFx0Y29uc3QgZGltZW5zaW9ucyA9IHRoaXMuY2FsY3VsYXRlRGltZW5zaW9ucygpO1xyXG5cdFx0Y29uc3Qgb2Zmc2V0ID0gdGhpcy5nZXRFbGVtZW50c09mZnNldCgpO1xyXG5cclxuXHRcdGxldCBzY3JvbGxTdGFydFBvc2l0aW9uID0gdGhpcy5nZXRTY3JvbGxTdGFydFBvc2l0aW9uKCk7XHJcblx0XHRpZiAoc2Nyb2xsU3RhcnRQb3NpdGlvbiA+IChkaW1lbnNpb25zLnNjcm9sbExlbmd0aCArIG9mZnNldCkgJiYgISh0aGlzLnBhcmVudFNjcm9sbCBpbnN0YW5jZW9mIFdpbmRvdykpIHtcclxuXHRcdFx0c2Nyb2xsU3RhcnRQb3NpdGlvbiA9IGRpbWVuc2lvbnMuc2Nyb2xsTGVuZ3RoO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0c2Nyb2xsU3RhcnRQb3NpdGlvbiAtPSBvZmZzZXQ7XHJcblx0XHR9XHJcblx0XHRzY3JvbGxTdGFydFBvc2l0aW9uID0gTWF0aC5tYXgoMCwgc2Nyb2xsU3RhcnRQb3NpdGlvbik7XHJcblxyXG5cdFx0Y29uc3QgcGFnZUluZm8gPSB0aGlzLmNhbGN1bGF0ZVBhZ2VJbmZvKHNjcm9sbFN0YXJ0UG9zaXRpb24sIGRpbWVuc2lvbnMpO1xyXG5cdFx0Y29uc3QgbmV3UGFkZGluZyA9IHRoaXMuY2FsY3VsYXRlUGFkZGluZyhwYWdlSW5mby5zdGFydEluZGV4V2l0aEJ1ZmZlciwgZGltZW5zaW9ucyk7XHJcblx0XHRjb25zdCBuZXdTY3JvbGxMZW5ndGggPSBkaW1lbnNpb25zLnNjcm9sbExlbmd0aDtcclxuXHJcblx0XHRyZXR1cm4ge1xyXG5cdFx0XHRzdGFydEluZGV4OiBwYWdlSW5mby5zdGFydEluZGV4LFxyXG5cdFx0XHRlbmRJbmRleDogcGFnZUluZm8uZW5kSW5kZXgsXHJcblx0XHRcdHN0YXJ0SW5kZXhXaXRoQnVmZmVyOiBwYWdlSW5mby5zdGFydEluZGV4V2l0aEJ1ZmZlcixcclxuXHRcdFx0ZW5kSW5kZXhXaXRoQnVmZmVyOiBwYWdlSW5mby5lbmRJbmRleFdpdGhCdWZmZXIsXHJcblx0XHRcdHBhZGRpbmc6IE1hdGgucm91bmQobmV3UGFkZGluZyksXHJcblx0XHRcdHNjcm9sbExlbmd0aDogTWF0aC5yb3VuZChuZXdTY3JvbGxMZW5ndGgpLFxyXG5cdFx0XHRzY3JvbGxTdGFydFBvc2l0aW9uOiBwYWdlSW5mby5zY3JvbGxTdGFydFBvc2l0aW9uLFxyXG5cdFx0XHRzY3JvbGxFbmRQb3NpdGlvbjogcGFnZUluZm8uc2Nyb2xsRW5kUG9zaXRpb24sXHJcblx0XHRcdG1heFNjcm9sbFBvc2l0aW9uOiBwYWdlSW5mby5tYXhTY3JvbGxQb3NpdGlvblxyXG5cdFx0fTtcclxuXHR9XHJcbn1cclxuXHJcbkBOZ01vZHVsZSh7XHJcblx0ZXhwb3J0czogW1ZpcnR1YWxTY3JvbGxlckNvbXBvbmVudF0sXHJcblx0ZGVjbGFyYXRpb25zOiBbVmlydHVhbFNjcm9sbGVyQ29tcG9uZW50XSxcclxuXHRpbXBvcnRzOiBbQ29tbW9uTW9kdWxlXSxcclxuXHRwcm92aWRlcnM6IFtcclxuXHRcdHtcclxuXHRcdFx0cHJvdmlkZTogJ3ZpcnR1YWwtc2Nyb2xsZXItZGVmYXVsdC1vcHRpb25zJyxcclxuXHRcdFx0dXNlRmFjdG9yeTogVklSVFVBTF9TQ1JPTExFUl9ERUZBVUxUX09QVElPTlNfRkFDVE9SWVxyXG5cdFx0fVxyXG5cdF1cclxufSlcclxuZXhwb3J0IGNsYXNzIFZpcnR1YWxTY3JvbGxlck1vZHVsZSB7IH0iXX0=
|
|
969
|
+
`, host: {
|
|
970
|
+
'[class.horizontal]': "horizontal",
|
|
971
|
+
'[class.vertical]': "!horizontal",
|
|
972
|
+
'[class.selfScroll]': "!parentScroll",
|
|
973
|
+
'[class.rtl]': "RTL"
|
|
974
|
+
}, styles: [":host{position:relative;display:block;-webkit-overflow-scrolling:touch}:host.horizontal.selfScroll{overflow-y:visible;overflow-x:auto}:host.horizontal.selfScroll.rtl{transform:scaleX(-1)}:host.vertical.selfScroll{overflow-y:auto;overflow-x:visible}.scrollable-content{top:0;left:0;width:100%;height:100%;max-width:100vw;max-height:100vh;position:absolute}.scrollable-content ::ng-deep>*{box-sizing:border-box}:host.horizontal{white-space:nowrap}:host.horizontal .scrollable-content{display:flex}:host.horizontal .scrollable-content ::ng-deep>*{flex-shrink:0;flex-grow:0;white-space:initial}:host.horizontal.rtl .scrollable-content ::ng-deep>*{transform:scaleX(-1)}.total-padding{position:absolute;top:0;left:0;height:1px;width:1px;transform-origin:0 0;opacity:0}:host.horizontal .total-padding{height:100%}\n"] }]
|
|
975
|
+
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
|
|
976
|
+
type: Inject,
|
|
977
|
+
args: [PLATFORM_ID]
|
|
978
|
+
}] }, { type: undefined, decorators: [{
|
|
979
|
+
type: Optional
|
|
980
|
+
}, {
|
|
981
|
+
type: Inject,
|
|
982
|
+
args: ['virtual-scroller-default-options']
|
|
983
|
+
}] }]; }, propDecorators: { disable: [{
|
|
984
|
+
type: Input
|
|
985
|
+
}], executeRefreshOutsideAngularZone: [{
|
|
986
|
+
type: Input
|
|
987
|
+
}], enableUnequalChildrenSizes: [{
|
|
988
|
+
type: Input
|
|
989
|
+
}], RTL: [{
|
|
990
|
+
type: Input
|
|
991
|
+
}], useMarginInsteadOfTranslate: [{
|
|
992
|
+
type: Input
|
|
993
|
+
}], modifyOverflowStyleOfParentScroll: [{
|
|
994
|
+
type: Input
|
|
995
|
+
}], stripedTable: [{
|
|
996
|
+
type: Input
|
|
997
|
+
}], scrollbarWidth: [{
|
|
998
|
+
type: Input
|
|
999
|
+
}], scrollbarHeight: [{
|
|
1000
|
+
type: Input
|
|
1001
|
+
}], childWidth: [{
|
|
1002
|
+
type: Input
|
|
1003
|
+
}], childHeight: [{
|
|
1004
|
+
type: Input
|
|
1005
|
+
}], ssrChildWidth: [{
|
|
1006
|
+
type: Input
|
|
1007
|
+
}], ssrChildHeight: [{
|
|
1008
|
+
type: Input
|
|
1009
|
+
}], ssrViewportWidth: [{
|
|
1010
|
+
type: Input
|
|
1011
|
+
}], ssrViewportHeight: [{
|
|
1012
|
+
type: Input
|
|
1013
|
+
}], bufferAmount: [{
|
|
1014
|
+
type: Input
|
|
1015
|
+
}], scrollAnimationTime: [{
|
|
1016
|
+
type: Input
|
|
1017
|
+
}], resizeBypassRefreshThreshold: [{
|
|
1018
|
+
type: Input
|
|
1019
|
+
}], scrollThrottlingTime: [{
|
|
1020
|
+
type: Input
|
|
1021
|
+
}], scrollDebounceTime: [{
|
|
1022
|
+
type: Input
|
|
1023
|
+
}], checkResizeInterval: [{
|
|
1024
|
+
type: Input
|
|
1025
|
+
}], items: [{
|
|
1026
|
+
type: Input
|
|
1027
|
+
}], compareItems: [{
|
|
1028
|
+
type: Input
|
|
1029
|
+
}], horizontal: [{
|
|
1030
|
+
type: Input
|
|
1031
|
+
}], parentScroll: [{
|
|
1032
|
+
type: Input
|
|
1033
|
+
}], vsChildRectChange: [{
|
|
1034
|
+
type: Output
|
|
1035
|
+
}], vsUpdate: [{
|
|
1036
|
+
type: Output
|
|
1037
|
+
}], vsChange: [{
|
|
1038
|
+
type: Output
|
|
1039
|
+
}], vsStart: [{
|
|
1040
|
+
type: Output
|
|
1041
|
+
}], vsEnd: [{
|
|
1042
|
+
type: Output
|
|
1043
|
+
}], contentElementRef: [{
|
|
1044
|
+
type: ViewChild,
|
|
1045
|
+
args: ['content', { read: ElementRef, static: true }]
|
|
1046
|
+
}], invisiblePaddingElementRef: [{
|
|
1047
|
+
type: ViewChild,
|
|
1048
|
+
args: ['invisiblePadding', { read: ElementRef, static: true }]
|
|
1049
|
+
}], headerElementRef: [{
|
|
1050
|
+
type: ContentChild,
|
|
1051
|
+
args: ['header', { read: ElementRef, static: false }]
|
|
1052
|
+
}], containerElementRef: [{
|
|
1053
|
+
type: ContentChild,
|
|
1054
|
+
args: ['container', { read: ElementRef, static: false }]
|
|
1055
|
+
}] } });
|
|
1056
|
+
export class VirtualScrollerModule {
|
|
1057
|
+
}
|
|
1058
|
+
VirtualScrollerModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: VirtualScrollerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
1059
|
+
VirtualScrollerModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.0.2", ngImport: i0, type: VirtualScrollerModule, declarations: [VirtualScrollerComponent], imports: [CommonModule], exports: [VirtualScrollerComponent] });
|
|
1060
|
+
VirtualScrollerModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: VirtualScrollerModule, providers: [
|
|
1061
|
+
{
|
|
1062
|
+
provide: 'virtual-scroller-default-options',
|
|
1063
|
+
useFactory: VIRTUAL_SCROLLER_DEFAULT_OPTIONS_FACTORY
|
|
1064
|
+
}
|
|
1065
|
+
], imports: [CommonModule] });
|
|
1066
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: VirtualScrollerModule, decorators: [{
|
|
1067
|
+
type: NgModule,
|
|
1068
|
+
args: [{
|
|
1069
|
+
exports: [VirtualScrollerComponent],
|
|
1070
|
+
declarations: [VirtualScrollerComponent],
|
|
1071
|
+
imports: [CommonModule],
|
|
1072
|
+
providers: [
|
|
1073
|
+
{
|
|
1074
|
+
provide: 'virtual-scroller-default-options',
|
|
1075
|
+
useFactory: VIRTUAL_SCROLLER_DEFAULT_OPTIONS_FACTORY
|
|
1076
|
+
}
|
|
1077
|
+
]
|
|
1078
|
+
}]
|
|
1079
|
+
}] });
|
|
1080
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlydHVhbC1zY3JvbGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1saWIvbGlzdC92aXJ0dWFsLXNjcm9sbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFTixTQUFTLEVBQ1QsWUFBWSxFQUNaLFVBQVUsRUFDVixZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFDTCxRQUFRLEVBS1IsUUFBUSxFQUNSLE1BQU0sRUFFTixTQUFTLEdBQ1QsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM1QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUVuRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFL0MsT0FBTyxLQUFLLEtBQUssTUFBTSxtQkFBbUIsQ0FBQTs7QUFjMUMsTUFBTSxVQUFVLHdDQUF3QztJQUN2RCxPQUFPO1FBQ04sbUJBQW1CLEVBQUUsSUFBSTtRQUN6QixpQ0FBaUMsRUFBRSxJQUFJO1FBQ3ZDLDRCQUE0QixFQUFFLENBQUM7UUFDL0IsbUJBQW1CLEVBQUUsR0FBRztRQUN4QixrQkFBa0IsRUFBRSxDQUFDO1FBQ3JCLG9CQUFvQixFQUFFLENBQUM7UUFDdkIsWUFBWSxFQUFFLEtBQUs7S0FDbkIsQ0FBQztBQUNILENBQUM7QUFzSEQsTUFBTSxPQUFPLHdCQUF3QjtJQThicEMsWUFDb0IsT0FBbUIsRUFDbkIsUUFBbUIsRUFDbkIsSUFBWSxFQUNyQixpQkFBb0MsRUFDekIsVUFBZSxFQUVwQyxPQUFzQztRQU5uQixZQUFPLEdBQVAsT0FBTyxDQUFZO1FBQ25CLGFBQVEsR0FBUixRQUFRLENBQVc7UUFDbkIsU0FBSSxHQUFKLElBQUksQ0FBUTtRQUNyQixzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBaGN4QyxXQUFNLEdBQUcsTUFBTSxDQUFDO1FB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O3VCQUFDLFFBQVEsRUFBRSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRTtnQkFJakQsbUJBQW1CO3NCQUQ1QixZQUFZO3VCQUFDLFdBQVcsRUFBRSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRTs7QUF1OEIvRCxNQUFNLE9BQU8scUJBQXFCOztrSEFBckIscUJBQXFCO21IQUFyQixxQkFBcUIsaUJBaHNDckIsd0JBQXdCLGFBd3JDMUIsWUFBWSxhQXhyQ1Ysd0JBQXdCO21IQWdzQ3hCLHFCQUFxQixhQVB0QjtRQUNWO1lBQ0MsT0FBTyxFQUFFLGtDQUFrQztZQUMzQyxVQUFVLEVBQUUsd0NBQXdDO1NBQ3BEO0tBQ0QsWUFOUyxZQUFZOzJGQVFWLHFCQUFxQjtrQkFYakMsUUFBUTttQkFBQztvQkFDVCxPQUFPLEVBQUUsQ0FBQyx3QkFBd0IsQ0FBQztvQkFDbkMsWUFBWSxFQUFFLENBQUMsd0JBQXdCLENBQUM7b0JBQ3hDLE9BQU8sRUFBRSxDQUFDLFlBQVksQ0FBQztvQkFDdkIsU0FBUyxFQUFFO3dCQUNWOzRCQUNDLE9BQU8sRUFBRSxrQ0FBa0M7NEJBQzNDLFVBQVUsRUFBRSx3Q0FBd0M7eUJBQ3BEO3FCQUNEO2lCQUNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuXHRDaGFuZ2VEZXRlY3RvclJlZixcclxuXHRDb21wb25lbnQsXHJcblx0Q29udGVudENoaWxkLFxyXG5cdEVsZW1lbnRSZWYsXHJcblx0RXZlbnRFbWl0dGVyLFxyXG5cdEluamVjdCxcclxuXHRJbnB1dCxcclxuXHROZ01vZHVsZSxcclxuXHROZ1pvbmUsXHJcblx0T25DaGFuZ2VzLFxyXG5cdE9uRGVzdHJveSxcclxuXHRPbkluaXQsXHJcblx0T3B0aW9uYWwsXHJcblx0T3V0cHV0LFxyXG5cdFJlbmRlcmVyMixcclxuXHRWaWV3Q2hpbGQsXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcblxyXG5pbXBvcnQgeyBQTEFURk9STV9JRCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBpc1BsYXRmb3JtU2VydmVyIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuXHJcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcblxyXG5pbXBvcnQgKiBhcyB0d2VlbiBmcm9tICdAdHdlZW5qcy90d2Vlbi5qcydcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgVmlydHVhbFNjcm9sbGVyRGVmYXVsdE9wdGlvbnMge1xyXG5cdGNoZWNrUmVzaXplSW50ZXJ2YWw6IG51bWJlclxyXG5cdG1vZGlmeU92ZXJmbG93U3R5bGVPZlBhcmVudFNjcm9sbDogYm9vbGVhbixcclxuXHRyZXNpemVCeXBhc3NSZWZyZXNoVGhyZXNob2xkOiBudW1iZXIsXHJcblx0c2Nyb2xsQW5pbWF0aW9uVGltZTogbnVtYmVyO1xyXG5cdHNjcm9sbERlYm91bmNlVGltZTogbnVtYmVyO1xyXG5cdHNjcm9sbFRocm90dGxpbmdUaW1lOiBudW1iZXI7XHJcblx0c2Nyb2xsYmFySGVpZ2h0PzogbnVtYmVyO1xyXG5cdHNjcm9sbGJhcldpZHRoPzogbnVtYmVyO1xyXG5cdHN0cmlwZWRUYWJsZTogYm9vbGVhblxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gVklSVFVBTF9TQ1JPTExFUl9ERUZBVUxUX09QVElPTlNfRkFDVE9SWSgpOiBWaXJ0dWFsU2Nyb2xsZXJEZWZhdWx0T3B0aW9ucyB7XHJcblx0cmV0dXJuIHtcclxuXHRcdGNoZWNrUmVzaXplSW50ZXJ2YWw6IDEwMDAsXHJcblx0XHRtb2RpZnlPdmVyZmxvd1N0eWxlT2ZQYXJlbnRTY3JvbGw6IHRydWUsXHJcblx0XHRyZXNpemVCeXBhc3NSZWZyZXNoVGhyZXNob2xkOiA1LFxyXG5cdFx0c2Nyb2xsQW5pbWF0aW9uVGltZTogNzUwLFxyXG5cdFx0c2Nyb2xsRGVib3VuY2VUaW1lOiAwLFxyXG5cdFx0c2Nyb2xsVGhyb3R0bGluZ1RpbWU6IDAsXHJcblx0XHRzdHJpcGVkVGFibGU6IGZhbHNlXHJcblx0fTtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBXcmFwR3JvdXBEaW1lbnNpb25zIHtcclxuXHRtYXhDaGlsZFNpemVQZXJXcmFwR3JvdXA6IFdyYXBHcm91cERpbWVuc2lvbltdO1xyXG5cdG51bWJlck9mS25vd25XcmFwR3JvdXBDaGlsZFNpemVzOiBudW1iZXI7XHJcblx0c3VtT2ZLbm93bldyYXBHcm91cENoaWxkSGVpZ2h0czogbnVtYmVyO1xyXG5cdHN1bU9mS25vd25XcmFwR3JvdXBDaGlsZFdpZHRoczogbnVtYmVyO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFdyYXBHcm91cERpbWVuc2lvbiB7XHJcblx0Y2hpbGRIZWlnaHQ6IG51bWJlcjtcclxuXHRjaGlsZFdpZHRoOiBudW1iZXI7XHJcblx0aXRlbXM6IGFueVtdO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIElEaW1lbnNpb25zIHtcclxuXHRjaGlsZEhlaWdodDogbnVtYmVyO1xyXG5cdGNoaWxkV2lkdGg6IG51bWJlcjtcclxuXHRpdGVtQ291bnQ6IG51bWJlcjtcclxuXHRpdGVtc1BlclBhZ2U6IG51bWJlcjtcclxuXHRpdGVtc1BlcldyYXBHcm91cDogbnVtYmVyO1xyXG5cdG1heFNjcm9sbFBvc2l0aW9uOiBudW1iZXI7XHJcblx0cGFnZUNvdW50X2ZyYWN0aW9uYWw6IG51bWJlcjtcclxuXHRzY3JvbGxMZW5ndGg6IG51bWJlcjtcclxuXHR2aWV3cG9ydExlbmd0aDogbnVtYmVyO1xyXG5cdHdyYXBHcm91cHNQZXJQYWdlOiBudW1iZXI7XHJcbn1cclxuXHJcbmV4cG9ydCB0eXBlIFNjcm9sbERpcmVjdGlvblR5cGUgPSAnYmFja3dhcmQnIHwgJ2ZvcndhcmQnO1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBJUGFnZUluZm8ge1xyXG5cdGVuZEluZGV4OiBudW1iZXI7XHJcblx0ZW5kSW5kZXhXaXRoQnVmZmVyOiBudW1iZXI7XHJcblx0bWF4U2Nyb2xsUG9zaXRpb246IG51bWJlcjtcclxuXHRzY3JvbGxFbmRQb3NpdGlvbjogbnVtYmVyO1xyXG5cdHNjcm9sbFN0YXJ0UG9zaXRpb246IG51bWJlcjtcclxuXHRzY3JvbGxEaXJlY3Rpb24/OiBTY3JvbGxEaXJlY3Rpb25UeXBlO1xyXG5cdHN0YXJ0SW5kZXg6IG51bWJlcjtcclxuXHRzdGFydEluZGV4V2l0aEJ1ZmZlcjogbnVtYmVyO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIElWaWV3cG9ydCBleHRlbmRzIElQYWdlSW5mbyB7XHJcblx0cGFkZGluZzogbnVtYmVyO1xyXG5cdHNjcm9sbExlbmd0aDogbnVtYmVyO1xyXG59XHJcblxyXG5AQ29tcG9uZW50KHtcclxuXHRzZWxlY3RvcjogJ3ZpcnR1YWwtc2Nyb2xsZXIsW3ZpcnR1YWxTY3JvbGxlcl0nLFxyXG5cdGV4cG9ydEFzOiAndmlydHVhbFNjcm9sbGVyJyxcclxuXHR0ZW1wbGF0ZTogYFxyXG4gICAgPGRpdiBjbGFzcz1cInRvdGFsLXBhZGRpbmdcIiAjaW52aXNpYmxlUGFkZGluZz48L2Rpdj5cclxuICAgIDxkaXYgY2xhc3M9XCJzY3JvbGxhYmxlLWNvbnRlbnRcIiAjY29udGVudD5cclxuICAgICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxyXG4gICAgPC9kaXY+XHJcbiAgYCxcclxuXHRob3N0OiB7XHJcblx0XHQnW2NsYXNzLmhvcml6b250YWxdJzogXCJob3Jpem9udGFsXCIsXHJcblx0XHQnW2NsYXNzLnZlcnRpY2FsXSc6IFwiIWhvcml6b250YWxcIixcclxuXHRcdCdbY2xhc3Muc2VsZlNjcm9sbF0nOiBcIiFwYXJlbnRTY3JvbGxcIixcclxuXHRcdCdbY2xhc3MucnRsXSc6IFwiUlRMXCJcclxuXHR9LFxyXG5cdHN0eWxlczogW2BcclxuICAgIDpob3N0IHtcclxuICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xyXG5cdCAgXHRkaXNwbGF5OiBibG9jaztcclxuICAgICAgLXdlYmtpdC1vdmVyZmxvdy1zY3JvbGxpbmc6IHRvdWNoO1xyXG4gICAgfVxyXG5cdFx0Omhvc3QuaG9yaXpvbnRhbC5zZWxmU2Nyb2xsIHtcclxuICAgICAgb3ZlcmZsb3cteTogdmlzaWJsZTtcclxuICAgICAgb3ZlcmZsb3cteDogYXV0bztcclxuXHRcdH1cclxuXHRcdDpob3N0Lmhvcml6b250YWwuc2VsZlNjcm9sbC5ydGwge1xyXG5cdFx0XHR0cmFuc2Zvcm06IHNjYWxlWCgtMSk7XHJcblx0XHR9XHJcblx0XHQ6aG9zdC52ZXJ0aWNhbC5zZWxmU2Nyb2xsIHtcclxuICAgICAgb3ZlcmZsb3cteTogYXV0bztcclxuICAgICAgb3ZlcmZsb3cteDogdmlzaWJsZTtcclxuXHRcdH1cclxuICAgIC5zY3JvbGxhYmxlLWNvbnRlbnQge1xyXG4gICAgICB0b3A6IDA7XHJcbiAgICAgIGxlZnQ6IDA7XHJcbiAgICAgIHdpZHRoOiAxMDAlO1xyXG4gICAgICBoZWlnaHQ6IDEwMCU7XHJcbiAgICAgIG1heC13aWR0aDogMTAwdnc7XHJcbiAgICAgIG1heC1oZWlnaHQ6IDEwMHZoO1xyXG4gICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XHJcbiAgICB9XHJcblx0XHQuc2Nyb2xsYWJsZS1jb250ZW50IDo6bmctZGVlcCA+ICoge1xyXG5cdFx0XHRib3gtc2l6aW5nOiBib3JkZXItYm94O1xyXG5cdFx0fVxyXG5cdFx0Omhvc3QuaG9yaXpvbnRhbCB7XHJcblx0XHRcdHdoaXRlLXNwYWNlOiBub3dyYXA7XHJcblx0XHR9XHJcblx0XHQ6aG9zdC5ob3Jpem9udGFsIC5zY3JvbGxhYmxlLWNvbnRlbnQge1xyXG5cdFx0XHRkaXNwbGF5OiBmbGV4O1xyXG5cdFx0fVxyXG5cdFx0Omhvc3QuaG9yaXpvbnRhbCAuc2Nyb2xsYWJsZS1jb250ZW50IDo6bmctZGVlcCA+ICoge1xyXG5cdFx0XHRmbGV4LXNocmluazogMDtcclxuXHRcdFx0ZmxleC1ncm93OiAwO1xyXG5cdFx0XHR3aGl0ZS1zcGFjZTogaW5pdGlhbDtcclxuXHRcdH1cclxuXHRcdDpob3N0Lmhvcml6b250YWwucnRsIC5zY3JvbGxhYmxlLWNvbnRlbnQgOjpuZy1kZWVwID4gKiB7XHJcblx0XHRcdHRyYW5zZm9ybTpzY2FsZVgoLTEpO1xyXG5cdFx0fVxyXG4gICAgLnRvdGFsLXBhZGRpbmcge1xyXG4gICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XHJcbiAgICAgIHRvcDogMDtcclxuICAgICAgbGVmdDogMDtcclxuICAgICAgaGVpZ2h0OiAxcHg7XHJcbiAgICAgIHdpZHRoOiAxcHg7XHJcbiAgICAgIHRyYW5zZm9ybS1vcmlnaW46IDAgMDtcclxuICAgICAgb3BhY2l0eTogMDtcclxuICAgIH1cclxuICAgIDpob3N0Lmhvcml6b250YWwgLnRvdGFsLXBhZGRpbmcge1xyXG4gICAgICBoZWlnaHQ6IDEwMCU7XHJcbiAgICB9XHJcbiAgYF1cclxufSlcclxuZXhwb3J0IGNsYXNzIFZpcnR1YWxTY3JvbGxlckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xyXG5cdHB1YmxpYyB2aWV3UG9ydEl0ZW1zOiBhbnlbXTtcclxuXHRwdWJsaWMgd2luZG93ID0gd2luZG93O1xyXG5cclxuXHRwdWJsaWMgZ2V0IHZpZXdQb3J0SW5mbygpOiBJUGFnZUluZm8ge1xyXG5cdFx0Y29uc3QgcGFnZUluZm86IElWaWV3cG9ydCA9IHRoaXMucHJldmlvdXNWaWV3UG9ydCB8fCA8YW55Pnt9O1xyXG5cdFx0cmV0dXJuIHtcclxuXHRcdFx0c3RhcnRJbmRleDogcGFnZUluZm8uc3RhcnRJbmRleCB8fCAwLFxyXG5cdFx0XHRlbmRJbmRleDogcGFnZUluZm8uZW5kSW5kZXggfHwgMCxcclxuXHRcdFx0c2Nyb2xsU3RhcnRQb3NpdGlvbjogcGFnZUluZm8uc2Nyb2xsU3RhcnRQb3NpdGlvbiB8fCAwLFxyXG5cdFx0XHRzY3JvbGxFbmRQb3NpdGlvbjogcGFnZUluZm8uc2Nyb2xsRW5kUG9zaXRpb24gfHwgMCxcclxuXHRcdFx0c2Nyb2xsRGlyZWN0aW9uOiBwYWdlSW5mby5zY3JvbGxEaXJlY3Rpb24gfHwgJ2ZvcndhcmQnLFxyXG5cdFx0XHRtYXhTY3JvbGxQb3NpdGlvbjogcGFnZUluZm8ubWF4U2Nyb2xsUG9zaXRpb24gfHwgMCxcclxuXHRcdFx0c3RhcnRJbmRleFdpdGhCdWZmZXI6IHBhZ2VJbmZvLnN0YXJ0SW5kZXhXaXRoQnVmZmVyIHx8IDAsXHJcblx0XHRcdGVuZEluZGV4V2l0aEJ1ZmZlcjogcGFnZUluZm8uZW5kSW5kZXhXaXRoQnVmZmVyIHx8IDAsXHJcblx0XHR9O1xyXG5cdH1cclxuXHJcblx0cHJvdGVjdGVkIF9kaXNhYmxlID0gZmFsc2U7XHJcblx0QElucHV0KClcclxuXHRwdWJsaWMgZ2V0IGRpc2FibGUoKTogYm9vbGVhbiB7XHJcblx0XHRyZXR1cm4gdGhpcy5fZGlzYWJsZTtcclxuXHR9XHJcblx0cHVibGljIHNldCBkaXNhYmxlKHZhbHVlOiBib29sZWFuKSB7XHJcblx0XHRpZiAodGhpcy5fZGlzYWJsZSA9PT0gdmFsdWUpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdHRoaXMuX2Rpc2FibGUgPSB2YWx1ZTtcclxuXHRcdGlmICh0aGlzLl9kaXNhYmxlKSB7XHJcblx0XHRcdHRoaXMucmVtb3ZlU2Nyb2xsRXZlbnRIYW5kbGVycygpO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0dGhpcy5hZGRTY3JvbGxFdmVudEhhbmRsZXJzKCk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRASW5wdXQoKVxyXG5cdHB1YmxpYyBleGVjdXRlUmVmcmVzaE91dHNpZGVBbmd1bGFyWm9uZSA9IGZhbHNlO1xyXG5cclxuXHRwcm90ZWN0ZWQgX2VuYWJsZVVuZXF1YWxDaGlsZHJlblNpemVzID0gZmFsc2U7XHJcblx0QElucHV0KClcclxuXHRwdWJsaWMgZ2V0IGVuYWJsZVVuZXF1YWxDaGlsZHJlblNpemVzKCk6IGJvb2xlYW4ge1xyXG5cdFx0cmV0dXJuIHRoaXMuX2VuYWJsZVVuZXF1YWxDaGlsZHJlblNpemVzO1xyXG5cdH1cclxuXHRwdWJsaWMgc2V0IGVuYWJsZVVuZXF1YWxDaGlsZHJlblNpemVzKHZhbHVlOiBib29sZWFuKSB7XHJcblx0XHRpZiAodGhpcy5fZW5hYmxlVW5lcXVhbENoaWxkcmVuU2l6ZXMgPT09IHZhbHVlKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHR0aGlzLl9lbmFibGVVbmVxdWFsQ2hpbGRyZW5TaXplcyA9IHZhbHVlO1xyXG5cdFx0dGhpcy5taW5NZWFzdXJlZENoaWxkV2lkdGggPSB1bmRlZmluZWQ7XHJcblx0XHR0aGlzLm1pbk1lYXN1cmVkQ2hpbGRIZWlnaHQgPSB1bmRlZmluZWQ7XHJcblx0fVxyXG5cclxuXHRASW5wdXQoKVxyXG5cdHB1YmxpYyBSVEwgPSBmYWxzZTtcclxuXHJcblx0QElucHV0KClcclxuXHRwdWJsaWMgdXNlTWFyZ2luSW5zdGVhZE9mVHJhbnNsYXRlID0gZmFsc2U7XHJcblxyXG5cdEBJbnB1dCgpXHJcblx0cHVibGljIG1vZGlmeU92ZXJmbG93U3R5bGVPZlBhcmVudFNjcm9sbDogYm9vbGVhbjtcclxuXHJcblx0QElucHV0KClcclxuXHRwdWJsaWMgc3RyaXBlZFRhYmxlOiBib29sZWFuO1xyXG5cclxuXHRASW5wdXQoKVxyXG5cdHB1YmxpYyBzY3JvbGxiYXJXaWR0aDogbnVtYmVyO1xyXG5cclxuXHRASW5wdXQoKVxyXG5cdHB1YmxpYyBzY3JvbGxiYXJIZWlnaHQ6IG51bWJlcjtcclxuXHJcblx0QElucHV0KClcclxuXHRwdWJsaWMgY2hpbGRXaWR0aDogbnVtYmVyO1xyXG5cclxuXHRASW5wdXQoKVxyXG5cdHB1YmxpYyBjaGlsZEhlaWdodDogbnVtYmVyO1xyXG5cclxuXHRASW5wdXQoKVxyXG5cdHB1YmxpYyBzc3JDaGlsZFdpZHRoOiBudW1iZXI7XHJcblxyXG5cdEBJbnB1dCgpXHJcblx0cHVibGljIHNzckNoaWxkSGVpZ2h0OiBudW1iZXI7XHJcblxyXG5cdEBJbnB1dCgpXHJcblx0cHVibGljIHNzclZpZXdwb3J0V2lkdGggPSAxOTIwO1xyXG5cclxuXHRASW5wdXQoKVxyXG5cdHB1YmxpYyBzc3JWaWV3cG9ydEhlaWdodCA9IDEwODA7XHJcblxyXG5cdHByb3RlY3RlZCBfYnVmZmVyQW1vdW50OiBudW1iZXI7XHJcblx0QElucHV0KClcclxuXHRwdWJsaWMgZ2V0IGJ1ZmZlckFtb3VudCgpOiBudW1iZXIge1xyXG5cdFx0aWYgKHR5cGVvZiAodGhpcy5fYnVmZmVyQW1vdW50KSA9PT0gJ251bWJlcicgJiYgdGhpcy5fYnVmZmVyQW1vdW50ID4gMCkge1xyXG5cdFx0XHRyZXR1cm4gdGhpcy5fYnVmZmVyQW1vdW50O1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0cmV0dXJuIHRoaXMuZW5hYmxlVW5lcXVhbENoaWxkcmVuU2l6ZXMgPyA1IDogMDtcclxuXHRcdH1cclxuXHR9XHJcblx0cHVibGljIHNldCBidWZmZXJBbW91bnQodmFsdWU6IG51bWJlcikge1xyXG5cdFx0dGhpcy5fYnVmZmVyQW1vdW50ID0gdmFsdWU7XHJcblx0fVxyXG5cclxuXHRASW5wdXQoKVxyXG5cdHB1YmxpYyBzY3JvbGxBbmltYXRpb25UaW1lOiBudW1iZXI7XHJcblxyXG5cdEBJbnB1dCgpXHJcblx0cHVibGljIHJlc2l6ZUJ5cGFzc1JlZnJlc2hUaHJlc2hvbGQ6IG51bWJlcjtcclxuXHJcblx0cHJvdGVjdGVkIF9zY3JvbGxUaHJvdHRsaW5nVGltZTogbnVtYmVyO1xyXG5cdEBJbnB1dCgpXHJcblx0cHVibGljIGdldCBzY3JvbGxUaHJvdHRsaW5nVGltZSgpOiBudW1iZXIge1xyXG5cdFx0cmV0dXJuIHRoaXMuX3Njcm9sbFRocm90dGxpbmdUaW1lO1xyXG5cdH1cclxuXHRwdWJsaWMgc2V0IHNjcm9sbFRocm90dGxpbmdUaW1lKHZhbHVlOiBudW1iZXIpIHtcclxuXHRcdHRoaXMuX3Njcm9sbFRocm90dGxpbmdUaW1lID0gdmFsdWU7XHJcblx0XHR0aGlzLnVwZGF0ZU9uU2Nyb2xsRnVuY3Rpb24oKTtcclxuXHR9XHJcblxyXG5cdHByb3RlY3RlZCBfc2Nyb2xsRGVib3VuY2VUaW1lOiBudW1iZXI7XHJcblx0QElucHV0KClcclxuXHRwdWJsaWMgZ2V0IHNjcm9sbERlYm91bmNlVGltZSgpOiBudW1iZXIge1xyXG5cdFx0cmV0dXJuIHRoaXMuX3Njcm9sbERlYm91bmNlVGltZTtcclxuXHR9XHJcblx0cHVibGljIHNldCBzY3JvbGxEZWJvdW5jZVRpbWUodmFsdWU6IG51bWJlcikge1xyXG5cdFx0dGhpcy5fc2Nyb2xsRGVib3VuY2VUaW1lID0gdmFsdWU7XHJcblx0XHR0aGlzLnVwZGF0ZU9uU2Nyb2xsRnVuY3Rpb24oKTtcclxuXHR9XHJcblxyXG5cdHByb3RlY3RlZCBvblNjcm9sbDogKCkgPT4gdm9pZDtcclxuXHRwcm90ZWN0ZWQgdXBkYXRlT25TY3JvbGxGdW5jdGlvbigpOiB2b2lkIHtcclxuXHRcdGlmICh0aGlzLnNjcm9sbERlYm91bmNlVGltZSkge1xyXG5cdFx0XHR0aGlzLm9uU2Nyb2xsID0gPGFueT50aGlzLmRlYm91bmNlKCgpID0+IHtcclxuXHRcdFx0XHR0aGlzLnJlZnJlc2hfaW50ZXJuYWwoZmFsc2UpO1xyXG5cdFx0XHR9LCB0aGlzLnNjcm9sbERlYm91bmNlVGltZSk7XHJcblx0XHR9XHJcblx0XHRlbHNlIGlmICh0aGlzLnNjcm9sbFRocm90dGxpbmdUaW1lKSB7XHJcblx0XHRcdHRoaXMub25TY3JvbGwgPSA8YW55PnRoaXMudGhyb3R0bGVUcmFpbGluZygoKSA9PiB7XHJcblx0XHRcdFx0dGhpcy5yZWZyZXNoX2ludGVybmFsKGZhbHNlKTtcclxuXHRcdFx0fSwgdGhpcy5zY3JvbGxUaHJvdHRsaW5nVGltZSk7XHJcblx0XHR9XHJcblx0XHRlbHNlIHtcclxuXHRcdFx0dGhpcy5vblNjcm9sbCA9ICgpID0+IHtcclxuXHRcdFx0XHR0aGlzLnJlZnJlc2hfaW50ZXJuYWwoZmFsc2UpO1xyXG5cdFx0XHR9O1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cHJvdGVjdGVkIGNoZWNrU2Nyb2xsRWxlbWVudFJlc2l6ZWRUaW1lcjogbnVtYmVyO1xyXG5cdHByb3RlY3RlZCBfY2hlY2tSZXNpemVJbnRlcnZhbDogbnVtYmVyO1xyXG5cdEBJbnB1dCgpXHJcblx0cHVibGljIGdldCBjaGVja1Jlc2l6ZUludGVydmFsKCk6IG51bWJlciB7XHJcblx0XHRyZXR1cm4gdGhpcy5fY2hlY2tSZXNpemVJbnRlcnZhbDtcclxuXHR9XHJcblx0cHVibGljIHNldCBjaGVja1Jlc2l6ZUludGVydmFsKHZhbHVlOiBudW1iZXIpIHtcclxuXHRcdGlmICh0aGlzLl9jaGVja1Jlc2l6ZUludGVydmFsID09PSB2YWx1ZSkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0dGhpcy5fY2hlY2tSZXNpemVJbnRlcnZhbCA9IHZhbHVlO1xyXG5cdFx0dGhpcy5hZGRTY3JvbGxFdmVudEhhbmRsZXJzKCk7XHJcblx0fVxyXG5cclxuXHRwcm90ZWN0ZWQgX2l0ZW1zOiBhbnlbXSA9IFtdO1xyXG5cdEBJbnB1dCgpXHJcblx0cHVibGljIGdldCBpdGVtcygpOiBhbnlbXSB7XHJcblx0XHRyZXR1cm4gdGhpcy5faXRlbXM7XHJcblx0fVxyXG5cdHB1YmxpYyBzZXQgaXRlbXModmFsdWU6IGFueVtdKSB7XHJcblx0XHRpZiAodmFsdWUgPT09IHRoaXMuX2l0ZW1zKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHR0aGlzLl9pdGVtcyA9IHZhbHVlIHx8IFtdO1xyXG5cdFx0dGhpcy5yZWZyZXNoX2ludGVybmFsKHRydWUpO1xyXG5cdH1cclxuXHJcblx0QElucHV0KClcclxuXHRwdWJsaWMgY29tcGFyZUl0ZW1zOiAoaXRlbTE6IGFueSwgaXRlbTI6IGFueSkgPT4gYm9vbGVhbiA9IChpdGVtMTogYW55LCBpdGVtMjogYW55KSA9PiBpdGVtMSA9PT0gaXRlbTI7XHJcblxyXG5cdHByb3RlY3RlZCBfaG9yaXpvbnRhbDogYm9vbGVhbjtcclxuXHRASW5wdXQoKVxyXG5cdHB1YmxpYyBnZXQgaG9yaXpvbnRhbCgpOiBib29sZWFuIHtcclxuXHRcdHJldHVybiB0aGlzLl9ob3Jpem9udGFsO1xyXG5cdH1cclxuXHRwdWJsaWMgc2V0IGhvcml6b250YWwodmFsdWU6IGJvb2xlYW4pIHtcclxuXHRcdHRoaXMuX2hvcml6b250YWwgPSB2YWx1ZTtcclxuXHRcdHRoaXMudXBkYXRlRGlyZWN0aW9uKCk7XHJcblx0fVxyXG5cclxuXHRwcm90ZWN0ZWQgcmV2ZXJ0UGFyZW50T3ZlcnNjcm9sbCgpOiB2b2lkIHtcclxuXHRcdGNvbnN0IHNjcm9sbEVsZW1lbnQgPSB0aGlzLmdldFNjcm9sbEVsZW1lbnQoKTtcclxuXHRcdGlmIChzY3JvbGxFbGVtZW50ICYmIHRoaXMub2xkUGFyZW50U2Nyb2xsT3ZlcmZsb3cpIHtcclxuXHRcdFx0c2Nyb2xsRWxlbWVudC5zdHlsZVsnb3ZlcmZsb3cteSddID0gdGhpcy5vbGRQYXJlbnRTY3JvbGxPdmVyZmxvdy55O1xyXG5cdFx0XHRzY3JvbGxFbGVtZW50LnN0eWxlWydvdmVyZmxvdy14J10gPSB0aGlzLm9sZFBhcmVudFNjcm9sbE92ZXJmbG93Lng7XHJcblx0XHR9XHJcblxyXG5cdFx0dGhpcy5vbGRQYXJlbnRTY3JvbGxPdmVyZmxvdyA9IHVuZGVmaW5lZDtcclxuXHR9XHJcblxyXG5cdHByb3RlY3RlZCBvbGRQYXJlbnRTY3JvbGxPdmVyZmxvdzogeyB4OiBzdHJpbmcsIHk6IHN0cmluZyB9O1xyXG5cdHByb3RlY3RlZCBfcGFyZW50U2Nyb2xsOiBFbGVtZW50IHwgV2luZG93O1xyXG5cdEBJbnB1dCgpXHJcblx0cHVibGljIGdldCBwYXJlbnRTY3JvbGwoKTogRWxlbWVudCB8IFdpbmRvdyB7XHJcblx0XHRyZXR1cm4gdGhpcy5fcGFyZW50U2Nyb2xsO1xyXG5cdH1cclxuXHRwdWJsaWMgc2V0IHBhcmVudFNjcm9sbCh2YWx1ZTogRWxlbWVudCB8IFdpbmRvdykge1xyXG5cdFx0aWYgKHRoaXMuX3BhcmVudFNjcm9sbCA9PT0gdmFsdWUpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdHRoaXMucmV2ZXJ0UGFyZW50T3ZlcnNjcm9sbCgpO1xyXG5cdFx0dGhpcy5fcGFyZW50U2Nyb2xsID0gdmFsdWU7XHJcblx0XHR0aGlzLmFkZFNjcm9sbEV2ZW50SGFuZGxlcnMoKTtcclxuXHJcblx0XHRjb25zdCBzY3JvbGxFbGVtZW50ID0gdGhpcy5nZXRTY3JvbGxFbGVtZW50KCk7XHJcblx0XHRpZiAodGhpcy5tb2RpZnlPdmVyZmxvd1N0eWxlT2ZQYXJlbnRTY3JvbGwgJiYgc2Nyb2xsRWxlbWVudCAhPT0gdGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQpIHtcclxuXHRcdFx0dGhpcy5vbGRQYXJlbnRTY3JvbGxPdmVyZmxvdyA9IHsgeDogc2Nyb2xsRWxlbWVudC5zdHlsZVsnb3ZlcmZsb3cteCddLCB5OiBzY3JvbGxFbGVtZW50LnN0eWxlWydvdmVyZmxvdy15J10gfTtcclxuXHRcdFx0c2Nyb2xsRWxlbWVudC5zdHlsZVsnb3ZlcmZsb3cteSddID0gdGhpcy5ob3Jpem9udGFsID8gJ3Zpc2libGUnIDogJ2F1dG8nO1xyXG5cdFx0XHRzY3JvbGxFbGVtZW50LnN0eWxlWydvdmVyZmxvdy14J10gPSB0aGlzLmhvcml6b250YWwgPyAnYXV0bycgOiAndmlzaWJsZSc7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvLyBwcml2YXRlIF9sYXN0Q2hpbGRSZWN0OiBET01SZWN0ID0gbnVsbDtcclxuXHJcblx0QE91dHB1dCgpXHJcblx0cHVibGljIHZzQ2hpbGRSZWN0Q2hhbmdlOiBFdmVudEVtaXR0ZXI8RE9NUmVjdD4gPSBuZXcgRXZlbnRFbWl0dGVyPERPTVJlY3Q+KCk7XHJcblxyXG5cdEBPdXRwdXQoKVxyXG5cdHB1YmxpYyB2c1VwZGF0ZTogRXZlbnRFbWl0dGVyPGFueVtdPiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55W10+KCk7XHJcblxyXG5cdEBPdXRwdXQoKVxyXG5cdHB1YmxpYyB2c0NoYW5nZTogRXZlbnRFbWl0dGVyPElQYWdlSW5mbz4gPSBuZXcgRXZlbnRFbWl0dGVyPElQYWdlSW5mbz4oKTtcclxuXHJcblx0QE91dHB1dCgpXHJcblx0cHVibGljIHZzU3RhcnQ6IEV2ZW50RW1pdHRlcjxJUGFnZUluZm8+ID0gbmV3IEV2ZW50RW1pdHRlcjxJUGFnZUluZm8+KCk7XHJcblxyXG5cdEBPdXRwdXQoKVxyXG5cdHB1YmxpYyB2c0VuZDogRXZlbnRFbWl0dGVyPElQYWdlSW5mbz4gPSBuZXcgRXZlbnRFbWl0dGVyPElQYWdlSW5mbz4oKTtcclxuXHJcblx0QFZpZXdDaGlsZCgnY29udGVudCcsIHsgcmVhZDogRWxlbWVudFJlZiwgc3RhdGljOiB0cnVlIH0pXHJcblx0cHVibGljIGNvbnRlbnRFbGVtZW50UmVmOiBFbGVtZW50UmVmO1xyXG5cclxuXHRAVmlld0NoaWxkKCdpbnZpc2libGVQYWRkaW5nJywgeyByZWFkOiBFbGVtZW50UmVmLCBzdGF0aWM6IHRydWUgfSlcclxuXHRwcm90ZWN0ZWQgaW52aXNpYmxlUGFkZGluZ0VsZW1lbnRSZWY6IEVsZW1lbnRSZWY7XHJcblxyXG5cdEBDb250ZW50Q2hpbGQoJ2hlYWRlcicsIHsgcmVhZDogRWxlbWVudFJlZiwgc3RhdGljOiBmYWxzZSB9KVxyXG5cdHByb3RlY3RlZCBoZWFkZXJFbGVtZW50UmVmOiBFbGVtZW50UmVmO1xyXG5cclxuXHRAQ29udGVudENoaWxkKCdjb250YWluZXInLCB7IHJlYWQ6IEVsZW1lbnRSZWYsIHN0YXRpYzogZmFsc2UgfSlcclxuXHRwcm90ZWN0ZWQgY29udGFpbmVyRWxlbWVudFJlZjogRWxlbWVudFJlZjtcclxuXHJcblx0cHVibGljIG5nT25Jbml0KCk6IHZvaWQge1xyXG5cdFx0dGhpcy5hZGRTY3JvbGxFdmVudEhhbmRsZXJzKCk7XHJcblx0fVxyXG5cclxuXHRwdWJsaWMgbmdPbkRlc3Ryb3koKTogdm9pZCB7XHJcblx0XHR0aGlzLnJlbW92ZVNjcm9sbEV2ZW50SGFuZGxlcnMoKTtcclxuXHRcdHRoaXMucmV2ZXJ0UGFyZW50T3ZlcnNjcm9sbCgpO1xyXG5cdH1cclxuXHJcblx0cHVibGljIG5nT25DaGFuZ2VzKGNoYW5nZXM6IGFueSk6IHZvaWQge1xyXG5cdFx0Y29uc3QgaW5kZXhMZW5ndGhDaGFuZ2VkID0gdGhpcy5jYWNoZWRJdGVtc0xlbmd0aCAhPT0gdGhpcy5pdGVtcy5sZW5ndGg7XHJcblx0XHR0aGlzLmNhY2hlZEl0ZW1zTGVuZ3RoID0gdGhpcy5pdGVtcy5sZW5ndGg7XHJcblxyXG5cdFx0Y29uc3QgZmlyc3RSdW46IGJvb2xlYW4gPSAhY2hhbmdlcy5pdGVtcyB8fCAhY2hhbmdlcy5pdGVtcy5wcmV2aW91c1ZhbHVlIHx8IGNoYW5nZXMuaXRlbXMucHJldmlvdXNWYWx1ZS5sZW5ndGggPT09IDA7XHJcblx0XHR0aGlzLnJlZnJlc2hfaW50ZXJuYWwoaW5kZXhMZW5ndGhDaGFuZ2VkIHx8IGZpcnN0UnVuKTtcclxuXHR9XHJcblxyXG5cdHB1YmxpYyBuZ0RvQ2hlY2soKTogdm9pZCB7XHJcblx0XHRpZiAodGhpcy5jYWNoZWRJdGVtc0xlbmd0aCAhPT0gdGhpcy5pdGVtcy5sZW5ndGgpIHtcclxuXHRcdFx0dGhpcy5jYWNoZWRJdGVtc0xlbmd0aCA9IHRoaXMuaXRlbXMubGVuZ3RoO1xyXG5cdFx0XHR0aGlzLnJlZnJlc2hfaW50ZXJuYWwodHJ1ZSk7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAodGhpcy5wcmV2aW91c1ZpZXdQb3J0ICYmIHRoaXMudmlld1BvcnRJdGVtcyAmJiB0aGlzLnZpZXdQb3J0SXRlbXMubGVuZ3RoID4gMCkge1xyXG5cdFx0XHRsZXQgaXRlbXNBcnJheUNoYW5nZWQgPSBmYWxzZTtcclxuXHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnZpZXdQb3J0SXRlbXMubGVuZ3RoOyArK2kpIHtcclxuXHRcdFx0XHRpZiAoIXRoaXMuY29tcGFyZUl0ZW1zKHRoaXMuaXRlbXNbdGhpcy5wcmV2aW91c1ZpZXdQb3J0LnN0YXJ0SW5kZXhXaXRoQnVmZmVyICsgaV0sIHRoaXMudmlld1BvcnRJdGVtc1tpXSkpIHtcclxuXHRcdFx0XHRcdGl0ZW1zQXJyYXlDaGFuZ2VkID0gdHJ1ZTtcclxuXHRcdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0XHRpZiAoaXRlbXNBcnJheUNoYW5nZWQpIHtcclxuXHRcdFx0XHR0aGlzLnJlZnJlc2hfaW50ZXJuYWwodHJ1ZSk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHB1YmxpYyByZWZyZXNoKHJlZnJlc2hDb21wbGV0ZWRDYWxsYmFjazogKCkgPT4gdm9pZCA9IHVuZGVmaW5lZCk6IHZvaWQge1xyXG5cdFx0dGhpcy5yZWZyZXNoX2ludGVybmFsKHRydWUsIHJlZnJlc2hDb21wbGV0ZWRDYWxsYmFjayk7XHJcblx0fVxyXG5cclxuXHRwdWJsaWMgaW52YWxpZGF0ZUFsbENhY2hlZE1lYXN1cmVtZW50cygpOiB2b2lkIHtcclxuXHRcdHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucyA9IHtcclxuXHRcdFx0bWF4Q2hpbGRTaXplUGVyV3JhcEdyb3VwOiBbXSxcclxuXHRcdFx0bnVtYmVyT2ZLbm93bldyYXBHcm91cENoaWxkU2l6ZXM6IDAsXHJcblx0XHRcdHN1bU9mS25vd25XcmFwR3JvdXBDaGlsZFdpZHRoczogMCxcclxuXHRcdFx0c3VtT2ZLbm93bldyYXBHcm91cENoaWxkSGVpZ2h0czogMFxyXG5cdFx0fTtcclxuXHJcblx0XHR0aGlzLm1pbk1lYXN1cmVkQ2hpbGRXaWR0aCA9IHVuZGVmaW5lZDtcclxuXHRcdHRoaXMubWluTWVhc3VyZWRDaGlsZEhlaWdodCA9IHVuZGVmaW5lZDtcclxuXHJcblx0XHR0aGlzLnJlZnJlc2hfaW50ZXJuYWwoZmFsc2UpO1xyXG5cdH1cclxuXHJcblx0cHVibGljIGludmFsaWRhdGVDYWNoZWRNZWFzdXJlbWVudEZvckl0ZW0oaXRlbTogYW55KTogdm9pZCB7XHJcblx0XHRpZiAodGhpcy5lbmFibGVVbmVxdWFsQ2hpbGRyZW5TaXplcykge1xyXG5cdFx0XHRjb25zdCBpbmRleCA9IHRoaXMuaXRlbXMgJiYgdGhpcy5pdGVtcy5pbmRleE9mKGl0ZW0pO1xyXG5cdFx0XHRpZiAoaW5kZXggPj0gMCkge1xyXG5cdFx0XHRcdHRoaXMuaW52YWxpZGF0ZUNhY2hlZE1lYXN1cmVtZW50QXRJbmRleChpbmRleCk7XHJcblx0XHRcdH1cclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHRoaXMubWluTWVhc3VyZWRDaGlsZFdpZHRoID0gdW5kZWZpbmVkO1xyXG5cdFx0XHR0aGlzLm1pbk1lYXN1cmVkQ2hpbGRIZWlnaHQgPSB1bmRlZmluZWQ7XHJcblx0XHR9XHJcblxyXG5cdFx0dGhpcy5yZWZyZXNoX2ludGVybmFsKGZhbHNlKTtcclxuXHR9XHJcblxyXG5cdHB1YmxpYyBpbnZhbGlkYXRlQ2FjaGVkTWVhc3VyZW1lbnRBdEluZGV4KGluZGV4OiBudW1iZXIpOiB2b2lkIHtcclxuXHRcdGlmICh0aGlzLmVuYWJsZVVuZXF1YWxDaGlsZHJlblNpemVzKSB7XHJcblx0XHRcdGNvbnN0IGNhY2hlZE1lYXN1cmVtZW50ID0gdGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLm1heENoaWxkU2l6ZVBlcldyYXBHcm91cFtpbmRleF07XHJcblx0XHRcdGlmIChjYWNoZWRNZWFzdXJlbWVudCkge1xyXG5cdFx0XHRcdHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5tYXhDaGlsZFNpemVQZXJXcmFwR3JvdXBbaW5kZXhdID0gdW5kZWZpbmVkO1xyXG5cdFx0XHRcdC0tdGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLm51bWJlck9mS25vd25XcmFwR3JvdXBDaGlsZFNpemVzO1xyXG5cdFx0XHRcdHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5zdW1PZktub3duV3JhcEdyb3VwQ2hpbGRXaWR0aHMgLT0gY2FjaGVkTWVhc3VyZW1lbnQuY2hpbGRXaWR0aCB8fCAwO1xyXG5cdFx0XHRcdHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5zdW1PZktub3duV3JhcEdyb3VwQ2hpbGRIZWlnaHRzIC09IGNhY2hlZE1lYXN1cmVtZW50LmNoaWxkSGVpZ2h0IHx8IDA7XHJcblx0XHRcdH1cclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHRoaXMubWluTWVhc3VyZWRDaGlsZFdpZHRoID0gdW5kZWZpbmVkO1xyXG5cdFx0XHR0aGlzLm1pbk1lYXN1cmVkQ2hpbGRIZWlnaHQgPSB1bmRlZmluZWQ7XHJcblx0XHR9XHJcblxyXG5cdFx0dGhpcy5yZWZyZXNoX2ludGVybmFsKGZhbHNlKTtcclxuXHR9XHJcblxyXG5cdHB1YmxpYyBzY3JvbGxJbnRvKGl0ZW06IGFueSwgYWxpZ25Ub0JlZ2lubmluZyA9IHRydWUsIGFkZGl0aW9uYWxPZmZzZXQgPSAwLCBhbmltYXRpb25NaWxsaXNlY29uZHM6IG51bWJlciA9IHVuZGVmaW5lZCwgYW5pbWF0aW9uQ29tcGxldGVkQ2FsbGJhY2s6ICgpID0+IHZvaWQgPSB1bmRlZmluZWQpOiB2b2lkIHtcclxuXHRcdGNvbnN0IGluZGV4OiBudW1iZXIgPSB0aGlzLml0ZW1zLmluZGV4T2YoaXRlbSk7XHJcblx0XHRpZiAoaW5kZXggPT09IC0xKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHR0aGlzLnNjcm9sbFRvSW5kZXgoaW5kZXgsIGFsaWduVG9CZWdpbm5pbmcsIGFkZGl0aW9uYWxPZmZzZXQsIGFuaW1hdGlvbk1pbGxpc2Vjb25kcywgYW5pbWF0aW9uQ29tcGxldGVkQ2FsbGJhY2spO1xyXG5cdH1cclxuXHJcblx0cHVibGljIHNjcm9sbFRvSW5kZXgoaW5kZXg6IG51bWJlciwgYWxpZ25Ub0JlZ2lubmluZyA9IHRydWUsIGFkZGl0aW9uYWxPZmZzZXQgPSAwLCBhbmltYXRpb25NaWxsaXNlY29uZHM6IG51bWJlciA9IHVuZGVmaW5lZCwgYW5pbWF0aW9uQ29tcGxldGVkQ2FsbGJhY2s6ICgpID0+IHZvaWQgPSB1bmRlZmluZWQpOiB2b2lkIHtcclxuXHRcdGxldCBtYXhSZXRyaWVzID0gNTtcclxuXHJcblx0XHRjb25zdCByZXRyeUlmTmVlZGVkID0gKCkgPT4ge1xyXG5cdFx0XHQtLW1heFJldHJpZXM7XHJcblx0XHRcdGlmIChtYXhSZXRyaWVzIDw9IDApIHtcclxuXHRcdFx0XHRpZiAoYW5pbWF0aW9uQ29tcGxldGVkQ2FsbGJhY2spIHtcclxuXHRcdFx0XHRcdGFuaW1hdGlvbkNvbXBsZXRlZENhbGxiYWNrKCk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Y29uc3QgZGltZW5zaW9ucyA9IHRoaXMuY2FsY3VsYXRlRGltZW5zaW9ucygpO1xyXG5cdFx0XHRjb25zdCBkZXNpcmVkU3RhcnRJbmRleCA9IE1hdGgubWluKE1hdGgubWF4KGluZGV4LCAwKSwgZGltZW5zaW9ucy5pdGVtQ291bnQgLSAxKTtcclxuXHRcdFx0aWYgKHRoaXMucHJldmlvdXNWaWV3UG9ydC5zdGFydEluZGV4ID09PSBkZXNpcmVkU3RhcnRJbmRleCkge1xyXG5cdFx0XHRcdGlmIChhbmltYXRpb25Db21wbGV0ZWRDYWxsYmFjaykge1xyXG5cdFx0XHRcdFx0YW5pbWF0aW9uQ29tcGxldGVkQ2FsbGJhY2soKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHR0aGlzLnNjcm9sbFRvSW5kZXhfaW50ZXJuYWwoaW5kZXgsIGFsaWduVG9CZWdpbm5pbmcsIGFkZGl0aW9uYWxPZmZzZXQsIDAsIHJldHJ5SWZOZWVkZWQpO1xyXG5cdFx0fTtcclxuXHJcblx0XHR0aGlzLnNjcm9sbFRvSW5kZXhfaW50ZXJuYWwoaW5kZXgsIGFsaWduVG9CZWdpbm5pbmcsIGFkZGl0aW9uYWxPZmZzZXQsIGFuaW1hdGlvbk1pbGxpc2Vjb25kcywgcmV0cnlJZk5lZWRlZCk7XHJcblx0fVxyXG5cclxuXHRwcm90ZWN0ZWQgc2Nyb2xsVG9JbmRleF9pbnRlcm5hbChpbmRleDogbnVtYmVyLCBhbGlnblRvQmVnaW5uaW5nID0gdHJ1ZSwgYWRkaXRpb25hbE9mZnNldCA9IDAsIGFuaW1hdGlvbk1pbGxpc2Vjb25kczogbnVtYmVyID0gdW5kZWZpbmVkLCBhbmltYXRpb25Db21wbGV0ZWRDYWxsYmFjazogKCkgPT4gdm9pZCA9IHVuZGVmaW5lZCk6IHZvaWQge1xyXG5cdFx0YW5pbWF0aW9uTWlsbGlzZWNvbmRzID0gYW5pbWF0aW9uTWlsbGlzZWNvbmRzID09PSB1bmRlZmluZWQgPyB0aGlzLnNjcm9sbEFuaW1hdGlvblRpbWUgOiBhbmltYXRpb25NaWxsaXNlY29uZHM7XHJcblxyXG5cdFx0Y29uc3QgZGltZW5zaW9ucyA9IHRoaXMuY2FsY3VsYXRlRGltZW5zaW9ucygpO1xyXG5cdFx0bGV0IHNjcm9sbCA9IHRoaXMuY2FsY3VsYXRlUGFkZGluZyhpbmRleCwgZGltZW5zaW9ucykgKyBhZGRpdGlvbmFsT2Zmc2V0O1xyXG5cdFx0aWYgKCFhbGlnblRvQmVnaW5uaW5nKSB7XHJcblx0XHRcdHNjcm9sbCAtPSBkaW1lbnNpb25zLndyYXBHcm91cHNQZXJQYWdlICogZGltZW5zaW9uc1t0aGlzLl9jaGlsZFNjcm9sbERpbV07XHJcblx0XHR9XHJcblxyXG5cdFx0dGhpcy5zY3JvbGxUb1Bvc2l0aW9uKHNjcm9sbCwgYW5pbWF0aW9uTWlsbGlzZWNvbmRzLCBhbmltYXRpb25Db21wbGV0ZWRDYWxsYmFjayk7XHJcblx0fVxyXG5cclxuXHRwdWJsaWMgc2Nyb2xsVG9Qb3NpdGlvbihzY3JvbGxQb3NpdGlvbjogbnVtYmVyLCBhbmltYXRpb25NaWxsaXNlY29uZHM6IG51bWJlciA9IHVuZGVmaW5lZCwgYW5pbWF0aW9uQ29tcGxldGVkQ2FsbGJhY2s6ICgpID0+IHZvaWQgPSB1bmRlZmluZWQpOiB2b2lkIHtcclxuXHRcdHNjcm9sbFBvc2l0aW9uICs9IHRoaXMuZ2V0RWxlbWVudHNPZmZzZXQoKTtcclxuXHJcblx0XHRhbmltYXRpb25NaWxsaXNlY29uZHMgPSBhbmltYXRpb25NaWxsaXNlY29uZHMgPT09IHVuZGVmaW5lZCA/IHRoaXMuc2Nyb2xsQW5pbWF0aW9uVGltZSA6IGFuaW1hdGlvbk1pbGxpc2Vjb25kcztcclxuXHJcblx0XHRjb25zdCBzY3JvbGxFbGVtZW50ID0gdGhpcy5nZXRTY3JvbGxFbGVtZW50KCk7XHJcblxyXG5cdFx0bGV0IGFuaW1hdGlvblJlcXVlc3Q6IG51bWJlcjtcclxuXHJcblx0XHRpZiAodGhpcy5jdXJyZW50VHdlZW4pIHtcclxuXHRcdFx0dGhpcy5jdXJyZW50VHdlZW4uc3RvcCgpO1xyXG5cdFx0XHR0aGlzLmN1cnJlbnRUd2VlbiA9IHVuZGVmaW5lZDtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoIWFuaW1hdGlvbk1pbGxpc2Vjb25kcykge1xyXG5cdFx0XHR0aGlzLnJlbmRlcmVyLnNldFByb3BlcnR5KHNjcm9sbEVsZW1lbnQsIHRoaXMuX3Njcm9sbFR5cGUsIHNjcm9sbFBvc2l0aW9uKTtcclxuXHRcdFx0dGhpcy5yZWZyZXNoX2ludGVybmFsKGZhbHNlLCBhbmltYXRpb25Db21wbGV0ZWRDYWxsYmFjayk7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHRjb25zdCB0d2VlbkNvbmZpZ09iaiA9IHsgc2Nyb2xsUG9zaXRpb246IHNjcm9sbEVsZW1lbnRbdGhpcy5fc2Nyb2xsVHlwZV0gfTtcclxuXHJcblx0XHRjb25zdCBuZXdUd2VlbiA9IG5ldyB0d2Vlbi5Ud2Vlbih0d2VlbkNvbmZpZ09iailcclxuXHRcdFx0LnRvKHsgc2Nyb2xsUG9zaXRpb24gfSwgYW5pbWF0aW9uTWlsbGlzZWNvbmRzKVxyXG5cdFx0XHQuZWFzaW5nKHR3ZWVuLkVhc2luZy5RdWFkcmF0aWMuT3V0KVxyXG5cdFx0XHQub25VcGRhdGUoKGRhdGEpID0+IHtcclxuXHRcdFx0XHRpZiAoaXNOYU4oZGF0YS5zY3JvbGxQb3NpdGlvbikpIHtcclxuXHRcdFx0XHRcdHJldHVybjtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0dGhpcy5yZW5kZXJlci5zZXRQcm9wZXJ0eShzY3JvbGxFbGVtZW50LCB0aGlzLl9zY3JvbGxUeXBlLCBkYXRhLnNjcm9sbFBvc2l0aW9uKTtcclxuXHRcdFx0XHR0aGlzLnJlZnJlc2hfaW50ZXJuYWwoZmFsc2UpO1xyXG5cdFx0XHR9KVxyXG5cdFx0XHQub25TdG9wKCgpID0+IHtcclxuXHRcdFx0XHRjYW5jZWxBbmltYXRpb25GcmFtZShhbmltYXRpb25SZXF1ZXN0KTtcclxuXHRcdFx0fSlcclxuXHRcdFx0LnN0YXJ0KCk7XHJcblxyXG5cdFx0Y29uc3QgYW5pbWF0ZSA9ICh0aW1lPzogbnVtYmVyKSA9PiB7XHJcblx0XHRcdGlmICghbmV3VHdlZW5bXCJpc1BsYXlpbmdcIl0oKSkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0bmV3VHdlZW4udXBkYXRlKHRpbWUpO1xyXG5cdFx0XHRpZiAodHdlZW5Db25maWdPYmouc2Nyb2xsUG9zaXRpb24gPT09IHNjcm9sbFBvc2l0aW9uKSB7XHJcblx0XHRcdFx0dGhpcy5yZWZyZXNoX2ludGVybmFsKGZhbHNlLCBhbmltYXRpb25Db21wbGV0ZWRDYWxsYmFjayk7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHR0aGlzLnpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xyXG5cdFx0XHRcdGFuaW1hdGlvblJlcXVlc3QgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoYW5pbWF0ZSk7XHJcblx0XHRcdH0pO1xyXG5cdFx0fTtcclxuXHJcblx0XHRhbmltYXRlKCk7XHJcblx0XHR0aGlzLmN1cnJlbnRUd2VlbiA9IG5ld1R3ZWVuO1xyXG5cdH1cclxuXHJcblx0cHJvdGVjdGVkIGlzQW5ndWxhclVuaXZlcnNhbFNTUjogYm9vbGVhbjtcclxuXHJcblx0Y29uc3RydWN0b3IoXHJcblx0XHRwcm90ZWN0ZWQgcmVhZG9ubHkgZWxlbWVudDogRWxlbWVudFJlZixcclxuXHRcdHByb3RlY3RlZCByZWFkb25seSByZW5kZXJlcjogUmVuZGVyZXIyLFxyXG5cdFx0cHJvdGVjdGVkIHJlYWRvbmx5IHpvbmU6IE5nWm9uZSxcclxuXHRcdHByb3RlY3RlZCBjaGFuZ2VEZXRlY3RvclJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcblx0XHRASW5qZWN0KFBMQVRGT1JNX0lEKSBwbGF0Zm9ybUlkOiBhbnksXHJcblx0XHRAT3B0aW9uYWwoKSBASW5qZWN0KCd2aXJ0dWFsLXNjcm9sbGVyLWRlZmF1bHQtb3B0aW9ucycpXHJcblx0XHRvcHRpb25zOiBWaXJ0dWFsU2Nyb2xsZXJEZWZhdWx0T3B0aW9uc1xyXG5cdCkge1xyXG5cclxuXHRcdHRoaXMuaXNBbmd1bGFyVW5pdmVyc2FsU1NSID0gaXNQbGF0Zm9ybVNlcnZlcihwbGF0Zm9ybUlkKTtcclxuXHJcblx0XHRjb25zdCBkZWZhdWx0T3B0aW9ucyA9IFZJUlRVQUxfU0NST0xMRVJfREVGQVVMVF9PUFRJT05TX0ZBQ1RPUlkoKTtcclxuXHJcblx0XHR0aGlzLmNoZWNrUmVzaXplSW50ZXJ2YWwgPSBvcHRpb25zPy5jaGVja1Jlc2l6ZUludGVydmFsIHx8IGRlZmF1bHRPcHRpb25zLmNoZWNrUmVzaXplSW50ZXJ2YWw7XHJcblx0XHR0aGlzLm1vZGlmeU92ZXJmbG93U3R5bGVPZlBhcmVudFNjcm9sbCA9IG9wdGlvbnM/Lm1vZGlmeU92ZXJmbG93U3R5bGVPZlBhcmVudFNjcm9sbCB8fCBkZWZhdWx0T3B0aW9ucy5tb2RpZnlPdmVyZmxvd1N0eWxlT2ZQYXJlbnRTY3JvbGw7XHJcblx0XHR0aGlzLnJlc2l6ZUJ5cGFzc1JlZnJlc2hUaHJlc2hvbGQgPSBvcHRpb25zPy5yZXNpemVCeXBhc3NSZWZyZXNoVGhyZXNob2xkIHx8IGRlZmF1bHRPcHRpb25zLnJlc2l6ZUJ5cGFzc1JlZnJlc2hUaHJlc2hvbGQ7XHJcblx0XHR0aGlzLnNjcm9sbEFuaW1hdGlvblRpbWUgPSBvcHRpb25zPy5zY3JvbGxBbmltYXRpb25UaW1lIHx8IGRlZmF1bHRPcHRpb25zLnNjcm9sbEFuaW1hdGlvblRpbWU7XHJcblx0XHR0aGlzLnNjcm9sbERlYm91bmNlVGltZSA9IG9wdGlvbnM/LnNjcm9sbERlYm91bmNlVGltZSB8fCBkZWZhdWx0T3B0aW9ucy5zY3JvbGxEZWJvdW5jZVRpbWU7XHJcblx0XHR0aGlzLnNjcm9sbFRocm90dGxpbmdUaW1lID0gb3B0aW9ucz8uc2Nyb2xsVGhyb3R0bGluZ1RpbWUgfHwgZGVmYXVsdE9wdGlvbnMuc2Nyb2xsVGhyb3R0bGluZ1RpbWU7XHJcblx0XHR0aGlzLnNjcm9sbGJhckhlaWdodCA9IG9wdGlvbnM/LnNjcm9sbGJhckhlaWdodCB8fCBkZWZhdWx0T3B0aW9ucy5zY3JvbGxiYXJIZWlnaHQ7XHJcblx0XHR0aGlzLnNjcm9sbGJhcldpZHRoID0gb3B0aW9ucz8uc2Nyb2xsYmFyV2lkdGggfHwgZGVmYXVsdE9wdGlvbnMuc2Nyb2xsYmFyV2lkdGg7XHJcblx0XHR0aGlzLnN0cmlwZWRUYWJsZSA9IG9wdGlvbnM/LnN0cmlwZWRUYWJsZSB8fCBkZWZhdWx0T3B0aW9ucy5zdHJpcGVkVGFibGU7XHJcblxyXG5cdFx0dGhpcy5ob3Jpem9udGFsID0gZmFsc2U7XHJcblx0XHR0aGlzLnJlc2V0V3JhcEdyb3VwRGltZW5zaW9ucygpO1xyXG5cdH1cclxuXHJcblx0cHVibGljIGdldEVsZW1lbnRTaXplKGVsZW1lbnQ6IEhUTUxFbGVtZW50KTogYW55IHtcclxuXHRcdGNvbnN0IHJlc3VsdCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcblx0XHRjb25zdCBzdHlsZXMgPSBnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpO1xyXG5cdFx0Y29uc3QgbWFyZ2luVG9wID0gcGFyc2VJbnQoc3R5bGVzWydtYXJnaW4tdG9wJ10sIDEwKSB8fCAwO1xyXG5cdFx0Y29uc3QgbWFyZ2luQm90dG9tID0gcGFyc2VJbnQoc3R5bGVzWydtYXJnaW4tYm90dG9tJ10sIDEwKSB8fCAwO1xyXG5cdFx0Y29uc3QgbWFyZ2luTGVmdCA9IHBhcnNlSW50KHN0eWxlc1snbWFyZ2luLWxlZnQnXSwgMTApIHx8IDA7XHJcblx0XHRjb25zdCBtYXJnaW5SaWdodCA9IHBhcnNlSW50KHN0eWxlc1snbWFyZ2luLXJpZ2h0J10sIDEwKSB8fCAwO1xyXG5cclxuXHRcdHJldHVybiB7XHJcblx0XHRcdHRvcDogcmVzdWx0LnRvcCArIG1hcmdpblRvcCxcclxuXHRcdFx0Ym90dG9tOiByZXN1bHQuYm90dG9tICsgbWFyZ2luQm90dG9tLFxyXG5cdFx0XHRsZWZ0OiByZXN1bHQubGVmdCArIG1hcmdpbkxlZnQsXHJcblx0XHRcdHJpZ2h0OiByZXN1bHQucmlnaHQgKyBtYXJnaW5SaWdodCxcclxuXHRcdFx0d2lkdGg6IHBhcnNlRmxvYXQoKHJlc3VsdC53aWR0aCArIG1hcmdpbkxlZnQgKyBtYXJnaW5SaWdodCkudG9GaXhlZCgzKSksXHJcblx0XHRcdGhlaWdodDogcGFyc2VGbG9hdCgocmVzdWx0LmhlaWdodCArIG1hcmdpblRvcCArIG1hcmdpbkJvdHRvbSkudG9GaXhlZCgzKSlcclxuXHRcdH07XHJcblx0fVxyXG5cclxuXHRwdWJsaWMgZ2V0Q29udGVudCgpIHtcclxuXHRcdGNvbnN0IGNvbnRlbnQgPSAodGhpcy5jb250YWluZXJFbGVtZW50UmVmICYmIHRoaXMuY29udGFpbmVyRWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KSB8fCB0aGlzLmNvbnRlbnRFbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XHJcblx0XHRyZXR1cm4gY29udGVudDtcclxuXHR9XHJcblxyXG5cdHByb3RlY3RlZCBwcmV2aW91c1Njcm9sbEJvdW5kaW5nUmVjdDogRE9NUmVjdDtcclxuXHRwcm90ZWN0ZWQgY2hlY2tTY3JvbGxFbGVtZW50UmVzaXplZCgpOiB2b2lkIHtcclxuXHRcdGNvbnN0IGJvdW5kaW5nUmVjdCA9IHRoaXMuZ2V0RWxlbWVudFNpemUodGhpcy5nZXRTY3JvbGxFbGVtZW50KCkpO1xyXG5cclxuXHRcdGxldCBzaXplQ2hhbmdlZDogYm9vbGVhbjtcclxuXHRcdGlmICghdGhpcy5wcmV2aW91c1Njcm9sbEJvdW5kaW5nUmVjdCkge1xyXG5cdFx0XHRzaXplQ2hhbmdlZCA9IHRydWU7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRjb25zdCB3aWR0aENoYW5nZSA9IE1hdGguYWJzKGJvdW5kaW5nUmVjdC53aWR0aCAtIHRoaXMucHJldmlvdXNTY3JvbGxCb3VuZGluZ1JlY3Qud2lkdGgpO1xyXG5cdFx0XHRjb25zdCBoZWlnaHRDaGFuZ2UgPSBNYXRoLmFicyhib3VuZGluZ1JlY3QuaGVpZ2h0IC0gdGhpcy5wcmV2aW91c1Njcm9sbEJvdW5kaW5nUmVjdC5oZWlnaHQpO1xyXG5cdFx0XHRzaXplQ2hhbmdlZCA9IHdpZHRoQ2hhbmdlID4gdGhpcy5yZXNpemVCeXBhc3NSZWZyZXNoVGhyZXNob2xkIHx8IGhlaWdodENoYW5nZSA+IHRoaXMucmVzaXplQnlwYXNzUmVmcmVzaFRocmVzaG9sZDtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoc2l6ZUNoYW5nZWQpIHtcclxuXHRcdFx0dGhpcy5wcmV2aW91c1Njcm9sbEJvdW5kaW5nUmVjdCA9IGJvdW5kaW5nUmVjdDtcclxuXHRcdFx0aWYgKGJvdW5kaW5nUmVjdC53aWR0aCA+IDAgJiYgYm91bmRpbmdSZWN0LmhlaWdodCA+IDApIHtcclxuXHRcdFx0XHR0aGlzLnJlZnJlc2hfaW50ZXJuYWwoZmFsc2UpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRwcm90ZWN0ZWQgX2ludmlzaWJsZVBhZGRpbmdQcm9wZXJ0eTtcclxuXHRwcm90ZWN0ZWQgX29mZnNldFR5cGU7XHJcblx0cHJvdGVjdGVkIF9zY3JvbGxUeXBlO1xyXG5cdHByb3RlY3RlZCBfcGFnZU9mZnNldFR5cGU7XHJcblx0cHJvdGVjdGVkIF9jaGlsZFNjcm9sbERpbTtcclxuXHRwcm90ZWN0ZWQgX3RyYW5zbGF0ZURpcjtcclxuXHRwcm90ZWN0ZWQgX21hcmdpbkRpcjtcclxuXHRwcm90ZWN0ZWQgdXBkYXRlRGlyZWN0aW9uKCk6IHZvaWQge1xyXG5cdFx0aWYgKHRoaXMuaG9yaXpvbnRhbCkge1xyXG5cdFx0XHR0aGlzLl9jaGlsZFNjcm9sbERpbSA9ICdjaGlsZFdpZHRoJztcclxuXHRcdFx0dGhpcy5faW52aXNpYmxlUGFkZGluZ1Byb3BlcnR5ID0gJ3NjYWxlWCc7XHJcblx0XHRcdHRoaXMuX21hcmdpbkRpciA9ICdtYXJnaW4tbGVmdCc7XHJcblx0XHRcdHRoaXMuX29mZnNldFR5cGUgPSAnb2Zmc2V0TGVmdCc7XHJcblx0XHRcdHRoaXMuX3BhZ2VPZmZzZXRUeXBlID0gJ3BhZ2VYT2Zmc2V0JztcclxuXHRcdFx0dGhpcy5fc2Nyb2xsVHlwZSA9ICdzY3JvbGxMZWZ0JztcclxuXHRcdFx0dGhpcy5fdHJhbnNsYXRlRGlyID0gJ3RyYW5zbGF0ZVgnO1xyXG5cdFx0fVxyXG5cdFx0ZWxzZSB7XHJcblx0XHRcdHRoaXMuX2NoaWxkU2Nyb2xsRGltID0gJ2NoaWxkSGVpZ2h0JztcclxuXHRcdFx0dGhpcy5faW52aXNpYmxlUGFkZGluZ1Byb3BlcnR5ID0gJ3NjYWxlWSc7XHJcblx0XHRcdHRoaXMuX21hcmdpbkRpciA9ICdtYXJnaW4tdG9wJztcclxuXHRcdFx0dGhpcy5fb2Zmc2V0VHlwZSA9ICdvZmZzZXRUb3AnO1xyXG5cdFx0XHR0aGlzLl9wYWdlT2Zmc2V0VHlwZSA9ICdwYWdlWU9mZnNldCc7XHJcblx0XHRcdHRoaXMuX3Njcm9sbFR5cGUgPSAnc2Nyb2xsVG9wJztcclxuXHRcdFx0dGhpcy5fdHJhbnNsYXRlRGlyID0gJ3RyYW5zbGF0ZVknO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cHJvdGVjdGVkIGRlYm91bmNlKGZ1bmM6ICgpID0+IHZvaWQsIHdhaXQ6IG51bWJlciwgLi4uYXJncyk6ICgpID0+IHZvaWQge1xyXG5cdFx0Y29uc3QgdGhyb3R0bGVkID0gdGhpcy50aHJvdHRsZVRyYWlsaW5nKGZ1bmMsIHdhaXQpO1xyXG5cdFx0Y29uc3QgcmVzdWx0ID0gZnVuY3Rpb24gKCkge1xyXG5cdFx0XHR0aHJvdHRsZWRbJ2NhbmNlbCddKCk7XHJcblx0XHRcdHRocm90dGxlZC5hcHBseSh0aGlzLCBhcmdzKTtcclxuXHRcdH07XHJcblx0XHRyZXN1bHRbJ2NhbmNlbCddID0gZnVuY3Rpb24gKCkge1xyXG5cdFx0XHR0aHJvdHRsZWRbJ2NhbmNlbCddKCk7XHJcblx0XHR9O1xyXG5cclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRwcm90ZWN0ZWQgdGhyb3R0bGVUcmFpbGluZyhmdW5jOiAoKSA9PiB2b2lkLCB3YWl0OiBudW1iZXIsIC4uLmFyZ3MpOiAoKSA9PiB2b2lkIHtcclxuXHRcdGxldCB0aW1lb3V0ID0gdW5kZWZpbmVkO1xyXG5cdFx0bGV0IF9hcmd1bWVudHMgPSBhcmdzO1xyXG5cdFx0Y29uc3QgcmVzdWx0ID0gZnVuY3Rpb24gKCkge1xyXG5cdFx0XHRjb25zdCBfdGhpcyA9IHRoaXM7XHJcblx0XHRcdF9hcmd1bWVudHMgPSBhcmdzXHJcblxyXG5cdFx0XHRpZiAodGltZW91dCkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aWYgKHdhaXQgPD0gMCkge1xyXG5cdFx0XHRcdGZ1bmMuYXBwbHkoX3RoaXMsIF9hcmd1bWVudHMpO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdHRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuXHRcdFx0XHRcdHRpbWVvdXQgPSB1bmRlZmluZWQ7XHJcblx0XHRcdFx0XHRmdW5jLmFwcGx5KF90aGlzLCBfYXJndW1lbnRzKTtcclxuXHRcdFx0XHR9LCB3YWl0KTtcclxuXHRcdFx0fVxyXG5cdFx0fTtcclxuXHRcdHJlc3VsdFsnY2FuY2VsJ10gPSBmdW5jdGlvbiAoKSB7XHJcblx0XHRcdGlmICh0aW1lb3V0KSB7XHJcblx0XHRcdFx0Y2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xyXG5cdFx0XHRcdHRpbWVvdXQgPSB1bmRlZmluZWQ7XHJcblx0XHRcdH1cclxuXHRcdH07XHJcblxyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHByb3RlY3RlZCBjYWxjdWxhdGVkU2Nyb2xsYmFyV2lkdGggPSAwO1xyXG5cdHByb3RlY3RlZCBjYWxjdWxhdGVkU2Nyb2xsYmFySGVpZ2h0ID0gMDtcclxuXHJcblx0cHJvdGVjdGVkIHBhZGRpbmcgPSAwO1xyXG5cdHByb3RlY3RlZCBwcmV2aW91c1ZpZXdQb3J0OiBJVmlld3BvcnQgPSA8YW55Pnt9O1xyXG5cdHByb3RlY3RlZCBjdXJyZW50VHdlZW46IHR3ZWVuLlR3ZWVuO1xyXG5cdHByb3RlY3RlZCBjYWNoZWRJdGVtc0xlbmd0aDogbnVtYmVyO1xyXG5cclxuXHRwcm90ZWN0ZWQgZGlzcG9zZVNjcm9sbEhhbmRsZXI6ICgpID0+IHZvaWQgfCB1bmRlZmluZWQ7XHJcblx0cHJvdGVjdGVkIGRpc3Bvc2VSZXNpemVIYW5kbGVyOiAoKSA9PiB2b2lkIHwgdW5kZWZpbmVkO1xyXG5cclxuXHRwcm90ZWN0ZWQgcmVmcmVzaF9pbnRlcm5hbChpdGVtc0FycmF5TW9kaWZpZWQ6IGJvb2xlYW4sIHJlZnJlc2hDb21wbGV0ZWRDYWxsYmFjazogKCkgPT4gdm9pZCA9IHVuZGVmaW5lZCwgbWF4UnVuVGltZXMgPSAyKTogdm9pZCB7XHJcblx0XHQvL25vdGU6IG1heFJ1blRpbWVzIGlzIHRvIGZvcmNlIGl0IHRvIGtlZXAgcmVjYWxjdWxhdGluZyBpZiB0aGUgcHJldmlvdXMgaXRlcmF0aW9uIGNhdXNlZCBhIHJlLXJlbmRlciAoZGlmZmVyZW50IHNsaWNlZCBpdGVtcyBpbiB2aWV3cG9ydCBvciBzY3JvbGxQb3NpdGlvbiBjaGFuZ2VkKS5cclxuXHRcdC8vVGhlIGRlZmF1bHQgb2YgMnggbWF4IHdpbGwgcHJvYmFibHkgYmUgYWNjdXJhdGUgZW5vdWdoIHdpdGhvdXQgY2F1c2luZyB0b28gbGFyZ2UgYSBwZXJmb3JtYW5jZSBib3R0bGVuZWNrXHJcblx0XHQvL1RoZSBjb2RlIHdvdWxkIHR5cGljYWxseSBxdWl0IG91dCBvbiB0aGUgMm5kIGl0ZXJhdGlvbiBhbnl3YXlzLiBUaGUgbWFpbiB0aW1lIGl0J2QgdGhpbmsgbW9yZSB0aGFuIDIgcnVucyB3b3VsZCBiZSBuZWNlc3Nhcnkgd291bGQgYmUgZm9yIHZhc3RseSBkaWZmZXJlbnQgc2l6ZWQgY2hpbGQgaXRlbXMgb3IgaWYgdGhpcyBpcyB0aGUgMXN0IHRpbWUgdGhlIGl0ZW1zIGFycmF5IHdhcyBpbml0aWFsaXplZC5cclxuXHRcdC8vV2l0aG91dCBtYXhSdW5UaW1lcywgSWYgdGhlIHVzZXIgaXMgYWN0aXZlbHkgc2Nyb2xsaW5nIHRoaXMgY29kZSB3b3VsZCBiZWNvbWUgYW4gaW5maW5pdGUgbG9vcCB1bnRpbCB0aGV5IHN0b3BwZWQgc2Nyb2xsaW5nLiBUaGlzIHdvdWxkIGJlIG9rYXksIGV4Y2VwdCBlYWNoIHNjcm9sbCBldmVudCB3b3VsZCBzdGFydCBhbiBhZGRpdGlvbmFsIGluZmludGUgbG9vcC4gV2Ugd2FudCB0byBzaG9ydC1jaXJjdWl0IGl0IHRvIHByZXZlbnQgdGhpcy5cclxuXHJcblx0XHRpZiAoaXRlbXNBcnJheU1vZGlmaWVkICYmIHRoaXMucHJldmlvdXNWaWV3UG9ydCAmJiB0aGlzLnByZXZpb3VzVmlld1BvcnQuc2Nyb2xsU3RhcnRQb3NpdGlvbiA+IDApIHtcclxuXHRcdFx0Ly9pZiBpdGVtcyB3ZXJlIHByZXBlbmRlZCwgc2Nyb2xsIGZvcndhcmQgdG8ga2VlcCBzYW1lIGl0ZW1zIHZpc2libGVcclxuXHRcdFx0Y29uc3Qgb2xkVmlld1BvcnQgPSB0aGlzLnByZXZpb3VzVmlld1BvcnQ7XHJcblx0XHRcdGNvbnN0IG9sZFZpZXdQb3J0SXRlbXMgPSB0aGlzLnZpZXdQb3J0SXRlbXM7XHJcblxyXG5cdFx0XHRjb25zdCBvbGRSZWZyZXNoQ29tcGxldGVkQ2FsbGJhY2sgPSByZWZyZXNoQ29tcGxldGVkQ2FsbGJhY2s7XHJcblx0XHRcdHJlZnJlc2hDb21wbGV0ZWRDYWxsYmFjayA9ICgpID0+IHtcclxuXHRcdFx0XHRjb25zdCBzY3JvbGxMZW5ndGhEZWx0YSA9IHRoaXMucHJldmlvdXNWaWV3UG9ydC5zY3JvbGxMZW5ndGggLSBvbGRWaWV3UG9ydC5zY3JvbGxMZW5ndGg7XHJcblx0XHRcdFx0aWYgKHNjcm9sbExlbmd0aERlbHRhID4gMCAmJiB0aGlzLnZpZXdQb3J0SXRlbXMpIHtcclxuXHRcdFx0XHRcdGNvbnN0IG9sZFN0YXJ0SXRlbSA9IG9sZFZpZXdQb3J0SXRlbXNbMF07XHJcblx0XHRcdFx0XHRjb25zdCBvbGRTdGFydEl0ZW1JbmRleCA9IHRoaXMuaXRlbXMuZmluZEluZGV4KHggPT4gdGhpcy5jb21wYXJlSXRlbXMob2xkU3RhcnRJdGVtLCB4KSk7XHJcblx0XHRcdFx0XHRpZiAob2xkU3RhcnRJdGVtSW5kZXggPiB0aGlzLnByZXZpb3VzVmlld1BvcnQuc3RhcnRJbmRleFdpdGhCdWZmZXIpIHtcclxuXHRcdFx0XHRcdFx0bGV0IGl0ZW1PcmRlckNoYW5nZWQgPSBmYWxzZTtcclxuXHRcdFx0XHRcdFx0Zm9yIChsZXQgaSA9IDE7IGkgPCB0aGlzLnZpZXdQb3J0SXRlbXMubGVuZ3RoOyArK2kpIHtcclxuXHRcdFx0XHRcdFx0XHRpZiAoIXRoaXMuY29tcGFyZUl0ZW1zKHRoaXMuaXRlbXNbb2xkU3RhcnRJdGVtSW5kZXggKyBpXSwgb2xkVmlld1BvcnRJdGVtc1tpXSkpIHtcclxuXHRcdFx0XHRcdFx0XHRcdGl0ZW1PcmRlckNoYW5nZWQgPSB0cnVlO1xyXG5cdFx0XHRcdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0XHRpZiAoIWl0ZW1PcmRlckNoYW5nZWQpIHtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLnNjcm9sbFRvUG9zaXRpb24odGhpcy5wcmV2aW91c1ZpZXdQb3J0LnNjcm9sbFN0YXJ0UG9zaXRpb24gKyBzY3JvbGxMZW5ndGhEZWx0YSwgMCwgb2xkUmVmcmVzaENvbXBsZXRlZENhbGxiYWNrKTtcclxuXHRcdFx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdGlmIChvbGRSZWZyZXNoQ29tcGxldGVkQ2FsbGJhY2spIHtcclxuXHRcdFx0XHRcdG9sZFJlZnJlc2hDb21wbGV0ZWRDYWxsYmFjaygpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fTtcclxuXHRcdH1cclxuXHJcblx0XHR0aGlzLnpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xyXG5cdFx0XHRyZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xyXG5cclxuXHRcdFx0XHRpZiAoaXRlbXNBcnJheU1vZGlmaWVkKSB7XHJcblx0XHRcdFx0XHR0aGlzLnJlc2V0V3JhcEdyb3VwRGltZW5zaW9ucygpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRjb25zdCB2aWV3cG9ydCA9IHRoaXMuY2FsY3VsYXRlVmlld3BvcnQoKTtcclxuXHJcblx0XHRcdFx0Y29uc3Qgc3RhcnRDaGFuZ2VkID0gaXRlbXNBcnJheU1vZGlmaWVkIHx8IHZpZXdwb3J0LnN0YXJ0SW5kZXggIT09IHRoaXMucHJldmlvdXNWaWV3UG9ydC5zdGFydEluZGV4O1xyXG5cdFx0XHRcdGNvbnN0IGVuZENoYW5nZWQgPSBpdGVtc0FycmF5TW9kaWZpZWQgfHwgdmlld3BvcnQuZW5kSW5kZXggIT09IHRoaXMucHJldmlvdXNWaWV3UG9ydC5lbmRJbmRleDtcclxuXHRcdFx0XHRjb25zdCBzY3JvbGxMZW5ndGhDaGFuZ2VkID0gdmlld3BvcnQuc2Nyb2xsTGVuZ3RoICE9PSB0aGlzLnByZXZpb3VzVmlld1BvcnQuc2Nyb2xsTGVuZ3RoO1xyXG5cdFx0XHRcdGNvbnN0IHBhZGRpbmdDaGFuZ2VkID0gdmlld3BvcnQucGFkZGluZyAhPT0gdGhpcy5wcmV2aW91c1ZpZXdQb3J0LnBhZGRpbmc7XHJcblx0XHRcdFx0Y29uc3Qgc2Nyb2xsUG9zaXRpb25DaGFuZ2VkID0gdmlld3BvcnQuc2Nyb2xsU3RhcnRQb3NpdGlvbiAhPT0gdGhpcy5wcmV2aW91c1ZpZXdQb3J0LnNjcm9sbFN0YXJ0UG9zaXRpb24gfHwgdmlld3BvcnQuc2Nyb2xsRW5kUG9zaXRpb24gIT09IHRoaXMucHJldmlvdXNWaWV3UG9ydC5zY3JvbGxFbmRQb3NpdGlvbiB8fCB2aWV3cG9ydC5tYXhTY3JvbGxQb3NpdGlvbiAhPT0gdGhpcy5wcmV2aW91c1ZpZXdQb3J0Lm1heFNjcm9sbFBvc2l0aW9uO1xyXG5cclxuXHRcdFx0XHRjb25zdCBzY3JvbGxEaXJlY3Rpb246IFNjcm9sbERpcmVjdGlvblR5cGUgPSB0aGlzLnByZXZpb3VzVmlld1BvcnQuZW5kSW5kZXggPD0gdmlld3BvcnQuZW5kSW5kZXggPyAnZm9yd2FyZCcgOiAnYmFja3dhcmQnO1xyXG5cdFx0XHRcdHRoaXMucHJldmlvdXNWaWV3UG9ydCA9IHZpZXdwb3J0O1xyXG5cclxuXHRcdFx0XHRpZiAoc2Nyb2xsTGVuZ3RoQ2hhbmdlZCkge1xyXG5cdFx0XHRcdFx0dGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmludmlzaWJsZVBhZGRpbmdFbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsICd0cmFuc2Zvcm0nLCBgJHt0aGlzLl9pbnZpc2libGVQYWRkaW5nUHJvcGVydHl9KCR7dmlld3BvcnQuc2Nyb2xsTGVuZ3RofSlgKTtcclxuXHRcdFx0XHRcdHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5pbnZpc2libGVQYWRkaW5nRWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCAnd2Via2l0VHJhbnNmb3JtJywgYCR7dGhpcy5faW52aXNpYmxlUGFkZGluZ1Byb3BlcnR5fSgke3ZpZXdwb3J0LnNjcm9sbExlbmd0aH0pYCk7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRpZiAocGFkZGluZ0NoYW5nZWQpIHtcclxuXHRcdFx0XHRcdGlmICh0aGlzLnVzZU1hcmdpbkluc3RlYWRPZlRyYW5zbGF0ZSkge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHRoaXMuY29udGVudEVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgdGhpcy5fbWFyZ2luRGlyLCBgJHt2aWV3cG9ydC5wYWRkaW5nfXB4YCk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRlbHNlIHtcclxuXHRcdFx0XHRcdFx0dGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmNvbnRlbnRFbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsICd0cmFuc2Zvcm0nLCBgJHt0aGlzLl90cmFuc2xhdGVEaXJ9KCR7dmlld3BvcnQucGFkZGluZ31weClgKTtcclxuXHRcdFx0XHRcdFx0dGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmNvbnRlbnRFbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsICd3ZWJraXRUcmFuc2Zvcm0nLCBgJHt0aGlzLl90cmFuc2xhdGVEaXJ9KCR7dmlld3BvcnQucGFkZGluZ31weClgKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdGlmICh0aGlzLmhlYWRlckVsZW1lbnRSZWYpIHtcclxuXHRcdFx0XHRcdGNvbnN0IHNjcm9sbFBvc2l0aW9uID0gdGhpcy5nZXRTY3JvbGxFbGVtZW50KClbdGhpcy5fc2Nyb2xsVHlwZV07XHJcblx0XHRcdFx0XHRjb25zdCBjb250YWluZXJPZmZzZXQgPSB0aGlzLmdldEVsZW1lbnRzT2Zmc2V0KCk7XHJcblx0XHRcdFx0XHRjb25zdCBvZmZzZXQgPSBNYXRoLm1heChzY3JvbGxQb3NpdGlvbiAtIHZpZXdwb3J0LnBhZGRpbmcgLSBjb250YWluZXJPZmZzZXQgKyB0aGlzLmhlYWRlckVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5jbGllbnRIZWlnaHQsIDApO1xyXG5cdFx0XHRcdFx0dGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmhlYWRlckVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgJ3RyYW5zZm9ybScsIGAke3RoaXMuX3RyYW5zbGF0ZURpcn0oJHtvZmZzZXR9cHgpYCk7XHJcblx0XHRcdFx0XHR0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHRoaXMuaGVhZGVyRWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCAnd2Via2l0VHJhbnNmb3JtJywgYCR7dGhpcy5fdHJhbnNsYXRlRGlyfSgke29mZnNldH1weClgKTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdGNvbnN0IGNoYW5nZUV2ZW50QXJnOiBJUGFnZUluZm8gPSAoc3RhcnRDaGFuZ2VkIHx8IGVuZENoYW5nZWQpID8ge1xyXG5cdFx0XHRcdFx0c3RhcnRJbmRleDogdmlld3BvcnQuc3RhcnRJbmRleCxcclxuXHRcdFx0XHRcdGVuZEluZGV4OiB2aWV3cG9ydC5lbmRJbmRleCxcclxuXHRcdFx0XHRcdHNjcm9sbFN0YXJ0UG9zaXRpb246IHZpZXdwb3J0LnNjcm9sbFN0YXJ0UG9zaXRpb24sXHJcblx0XHRcdFx0XHRzY3JvbGxFbmRQb3NpdGlvbjogdmlld3BvcnQuc2Nyb2xsRW5kUG9zaXRpb24sXHJcblx0XHRcdFx0XHRzY3JvbGxEaXJlY3Rpb246IHNjcm9sbERpcmVjdGlvbixcclxuXHRcdFx0XHRcdHN0YXJ0SW5kZXhXaXRoQnVmZmVyOiB2aWV3cG9ydC5zdGFydEluZGV4V2l0aEJ1ZmZlcixcclxuXHRcdFx0XHRcdGVuZEluZGV4V2l0aEJ1ZmZlcjogdmlld3BvcnQuZW5kSW5kZXhXaXRoQnVmZmVyLFxyXG5cdFx0XHRcdFx0bWF4U2Nyb2xsUG9zaXRpb246IHZpZXdwb3J0Lm1heFNjcm9sbFBvc2l0aW9uLFxyXG5cdFx0XHRcdH0gOiB1bmRlZmluZWQ7XHJcblxyXG5cclxuXHRcdFx0XHRpZiAoc3RhcnRDaGFuZ2VkIHx8IGVuZENoYW5nZWQgfHwgc2Nyb2xsUG9zaXRpb25DaGFuZ2VkKSB7XHJcblx0XHRcdFx0XHRjb25zdCBoYW5kbGVDaGFuZ2VkID0gKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHQvLyB1cGRhdGUgdGhlIHNjcm9sbCBsaXN0IHRvIHRyaWdnZXIgcmUtcmVuZGVyIG9mIGNvbXBvbmVudHMgaW4gdmlld3BvcnRcclxuXHRcdFx0XHRcdFx0dGhpcy52aWV3UG9ydEl0ZW1zID0gdmlld3BvcnQuc3RhcnRJbmRleFdpdGhCdWZmZXIgPj0gMCAmJiB2aWV3cG9ydC5lbmRJbmRleFdpdGhCdWZmZXIgPj0gMCA/IHRoaXMuaXRlbXMuc2xpY2Uodmlld3BvcnQuc3RhcnRJbmRleFdpdGhCdWZmZXIsIHZpZXdwb3J0LmVuZEluZGV4V2l0aEJ1ZmZlciArIDEpIDogW107XHJcblx0XHRcdFx0XHRcdHRoaXMudnNVcGRhdGUuZW1pdCh0aGlzLnZpZXdQb3J0SXRlbXMpO1xyXG5cclxuXHRcdFx0XHRcdFx0aWYgKHN0YXJ0Q2hhbmdlZCkge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMudnNTdGFydC5lbWl0KGNoYW5nZUV2ZW50QXJnKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdFx0aWYgKGVuZENoYW5nZWQpIHtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLnZzRW5kLmVtaXQoY2hhbmdlRXZlbnRBcmcpO1xyXG5cdFx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0XHRpZiAoc3RhcnRDaGFuZ2VkIHx8IGVuZENoYW5nZWQpIHtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLmNoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMudnNDaGFuZ2UuZW1pdChjaGFuZ2VFdmVudEFyZyk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHRcdGlmIChtYXhSdW5UaW1lcyA+IDApIHtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLnJlZnJlc2hfaW50ZXJuYWwoZmFsc2UsIHJlZnJlc2hDb21wbGV0ZWRDYWxsYmFjaywgbWF4UnVuVGltZXMgLSAxKTtcclxuXHRcdFx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHRcdGlmIChyZWZyZXNoQ29tcGxldGVkQ2FsbGJhY2spIHtcclxuXHRcdFx0XHRcdFx0XHRyZWZyZXNoQ29tcGxldGVkQ2FsbGJhY2soKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fTtcclxuXHJcblxyXG5cdFx0XHRcdFx0aWYgKHRoaXMuZXhlY3V0ZVJlZnJlc2hPdXRzaWRlQW5ndWxhclpvbmUpIHtcclxuXHRcdFx0XHRcdFx0aGFuZGxlQ2hhbmdlZCgpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0ZWxzZSB7XHJcblx0XHRcdFx0XHRcdHRoaXMuem9uZS5ydW4oaGFuZGxlQ2hhbmdlZCk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdGlmIChtYXhSdW5UaW1lcyA+IDAgJiYgKHNjcm9sbExlbmd0aENoYW5nZWQgfHwgcGFkZGluZ0NoYW5nZWQpKSB7XHJcblx0XHRcdFx0XHRcdHRoaXMucmVmcmVzaF9pbnRlcm5hbChmYWxzZSwgcmVmcmVzaENvbXBsZXRlZENhbGxiYWNrLCBtYXhSdW5UaW1lcyAtIDEpO1xyXG5cdFx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0aWYgKHJlZnJlc2hDb21wbGV0ZWRDYWxsYmFjaykge1xyXG5cdFx0XHRcdFx0XHRyZWZyZXNoQ29tcGxldGVkQ2FsbGJhY2soKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHRwcm90ZWN0ZWQgZ2V0U2Nyb2xsRWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XHJcblx0XHRyZXR1cm4gdGhpcy5wYXJlbnRTY3JvbGwgaW5zdGFuY2VvZiBXaW5kb3cgPyBkb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCB8fCBkb2N1bWVudC5ib2R5IDogdGhpcy5wYXJlbnRTY3JvbGwgfHwgdGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQ7XHJcblx0fVxyXG5cclxuXHRwcm90ZWN0ZWQgYWRkU2Nyb2xsRXZlbnRIYW5kbGVycygpOiB2b2lkIHtcclxuXHRcdGlmICh0aGlzLmlzQW5ndWxhclVuaXZlcnNhbFNTUikge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0Y29uc3Qgc2Nyb2xsRWxlbWVudCA9IHRoaXMuZ2V0U2Nyb2xsRWxlbWVudCgpO1xyXG5cclxuXHRcdHRoaXMucmVtb3ZlU2Nyb2xsRXZlbnRIYW5kbGVycygpO1xyXG5cclxuXHRcdHRoaXMuem9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XHJcblx0XHRcdGlmICh0aGlzLnBhcmVudFNjcm9sbCBpbnN0YW5jZW9mIFdpbmRvdykge1xyXG5cdFx0XHRcdHRoaXMuZGlzcG9zZVNjcm9sbEhhbmRsZXIgPSB0aGlzLnJlbmRlcmVyLmxpc3Rlbignd2luZG93JywgJ3Njcm9sbCcsIHRoaXMub25TY3JvbGwpO1xyXG5cdFx0XHRcdHRoaXMuZGlzcG9zZVJlc2l6ZUhhbmRsZXIgPSB0aGlzLnJlbmRlcmVyLmxpc3Rlbignd2luZG93JywgJ3Jlc2l6ZScsIHRoaXMub25TY3JvbGwpO1xyXG5cdFx0XHR9XHJcblx0XHRcdGVsc2Uge1xyXG5cdFx0XHRcdHRoaXMuZGlzcG9zZVNjcm9sbEhhbmRsZXIgPSB0aGlzLnJlbmRlcmVyLmxpc3RlbihzY3JvbGxFbGVtZW50LCAnc2Nyb2xsJywgdGhpcy5vblNjcm9sbCk7XHJcblx0XHRcdFx0aWYgKHRoaXMuX2NoZWNrUmVzaXplSW50ZXJ2YWwgPiAwKSB7XHJcblx0XHRcdFx0XHR0aGlzLmNoZWNrU2Nyb2xsRWxlbWVudFJlc2l6ZWRUaW1lciA9IDxhbnk+c2V0SW50ZXJ2YWwoKCkgPT4geyB0aGlzLmNoZWNrU2Nyb2xsRWxlbWVudFJlc2l6ZWQoKTsgfSwgdGhpcy5fY2hlY2tSZXNpemVJbnRlcnZhbCk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG5cdHByb3RlY3RlZCByZW1vdmVTY3JvbGxFdmVudEhhbmRsZXJzKCk6IHZvaWQge1xyXG5cdFx0aWYgKHRoaXMuY2hlY2tTY3JvbGxFbGVtZW50UmVzaXplZFRpbWVyKSB7XHJcblx0XHRcdGNsZWFySW50ZXJ2YWwodGhpcy5jaGVja1Njcm9sbEVsZW1lbnRSZXNpemVkVGltZXIpO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICh0aGlzLmRpc3Bvc2VTY3JvbGxIYW5kbGVyKSB7XHJcblx0XHRcdHRoaXMuZGlzcG9zZVNjcm9sbEhhbmRsZXIoKTtcclxuXHRcdFx0dGhpcy5kaXNwb3NlU2Nyb2xsSGFuZGxlciA9IHVuZGVmaW5lZDtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAodGhpcy5kaXNwb3NlUmVzaXplSGFuZGxlcikge1xyXG5cdFx0XHR0aGlzLmRpc3Bvc2VSZXNpemVIYW5kbGVyKCk7XHJcblx0XHRcdHRoaXMuZGlzcG9zZVJlc2l6ZUhhbmRsZXIgPSB1bmRlZmluZWQ7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRwcm90ZWN0ZWQgZ2V0RWxlbWVudHNPZmZzZXQoKTogbnVtYmVyIHtcclxuXHRcdGlmICh0aGlzLmlzQW5ndWxhclVuaXZlcnNhbFNTUikge1xyXG5cdFx0XHRyZXR1cm4gMDtcclxuXHRcdH1cclxuXHJcblx0XHRsZXQgb2Zmc2V0ID0gMDtcclxuXHJcblx0XHRpZiAodGhpcy5jb250YWluZXJFbGVtZW50UmVmICYmIHRoaXMuY29udGFpbmVyRWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KSB7XHJcblx0XHRcdG9mZnNldCArPSB0aGlzLmNvbnRhaW5lckVsZW1lbnRSZWYubmF0aXZlRWxlbWVudFt0aGlzLl9vZmZzZXRUeXBlXTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAodGhpcy5wYXJlbnRTY3JvbGwpIHtcclxuXHRcdFx0Y29uc3Qgc2Nyb2xsRWxlbWVudCA9IHRoaXMuZ2V0U2Nyb2xsRWxlbWVudCgpO1xyXG5cdFx0XHRjb25zdCBlbGVtZW50Q2xpZW50UmVjdCA9IHRoaXMuZ2V0RWxlbWVudFNpemUodGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQpO1xyXG5cdFx0XHRjb25zdCBzY3JvbGxDbGllbnRSZWN0ID0gdGhpcy5nZXRFbGVtZW50U2l6ZShzY3JvbGxFbGVtZW50KTtcclxuXHRcdFx0aWYgKHRoaXMuaG9yaXpvbnRhbCkge1xyXG5cdFx0XHRcdG9mZnNldCArPSBlbGVtZW50Q2xpZW50UmVjdC5sZWZ0IC0gc2Nyb2xsQ2xpZW50UmVjdC5sZWZ0O1xyXG5cdFx0XHR9XHJcblx0XHRcdGVsc2Uge1xyXG5cdFx0XHRcdG9mZnNldCArPSBlbGVtZW50Q2xpZW50UmVjdC50b3AgLSBzY3JvbGxDbGllbnRSZWN0LnRvcDtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aWYgKCEodGhpcy5wYXJlbnRTY3JvbGwgaW5zdGFuY2VvZiBXaW5kb3cpKSB7XHJcblx0XHRcdFx0b2Zmc2V0ICs9IHNjcm9sbEVsZW1lbnRbdGhpcy5fc2Nyb2xsVHlwZV07XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gb2Zmc2V0O1xyXG5cdH1cclxuXHJcblx0cHJvdGVjdGVkIGNvdW50SXRlbXNQZXJXcmFwR3JvdXAoKTogbnVtYmVyIHtcclxuXHRcdGlmICh0aGlzLmlzQW5ndWxhclVuaXZlcnNhbFNTUikge1xyXG5cdFx0XHRyZXR1cm4gTWF0aC5yb3VuZCh0aGlzLmhvcml6b250YWwgPyB0aGlzLnNzclZpZXdwb3J0SGVpZ2h0IC8gdGhpcy5zc3JDaGlsZEhlaWdodCA6IHRoaXMuc3NyVmlld3BvcnRXaWR0aCAvIHRoaXMuc3NyQ2hpbGRXaWR0aCk7XHJcblx0XHR9XHJcblxyXG5cdFx0Y29uc3QgcHJvcGVydHlOYW1lID0gdGhpcy5ob3Jpem9udGFsID8gJ29mZnNldExlZnQnIDogJ29mZnNldFRvcCc7XHJcblx0XHRjb25zdCBjaGlsZHJlbiA9IHRoaXMuZ2V0Q29udGVudCgpLmNoaWxkcmVuO1xyXG5cclxuXHRcdGNvbnN0IGNoaWxkcmVuTGVuZ3RoID0gY2hpbGRyZW4gPyBjaGlsZHJlbi5sZW5ndGggOiAwO1xyXG5cdFx0aWYgKGNoaWxkcmVuTGVuZ3RoID09PSAwKSB7XHJcblx0XHRcdHJldHVybiAxO1xyXG5cdFx0fVxyXG5cclxuXHRcdGNvbnN0IGZpcnN0T2Zmc2V0ID0gY2hpbGRyZW5bMF1bcHJvcGVydHlOYW1lXTtcclxuXHRcdGxldCByZXN1bHQgPSAxO1xyXG5cdFx0d2hpbGUgKHJlc3VsdCA8IGNoaWxkcmVuTGVuZ3RoICYmIGZpcnN0T2Zmc2V0ID09PSBjaGlsZHJlbltyZXN1bHRdW3Byb3BlcnR5TmFtZV0pIHtcclxuXHRcdFx0KytyZXN1bHQ7XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHByb3RlY3RlZCBnZXRTY3JvbGxTdGFydFBvc2l0aW9uKCk6IG51bWJlciB7XHJcblx0XHRsZXQgd2luZG93U2Nyb2xsVmFsdWUgPSB1bmRlZmluZWQ7XHJcblx0XHRpZiAodGhpcy5wYXJlbnRTY3JvbGwgaW5zdGFuY2VvZiBXaW5kb3cpIHtcclxuXHRcdFx0d2luZG93U2Nyb2xsVmFsdWUgPSB3aW5kb3dbdGhpcy5fcGFnZU9mZnNldFR5cGVdO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB3aW5kb3dTY3JvbGxWYWx1ZSB8fCB0aGlzLmdldFNjcm9sbEVsZW1lbnQoKVt0aGlzLl9zY3JvbGxUeXBlXSB8fCAwO1xyXG5cdH1cclxuXHJcblx0cHJvdGVjdGVkIG1pbk1lYXN1cmVkQ2hpbGRXaWR0aDogbnVtYmVyO1xyXG5cdHByb3RlY3RlZCBtaW5NZWFzdXJlZENoaWxkSGVpZ2h0OiBudW1iZXI7XHJcblxyXG5cdHByb3RlY3RlZCB3cmFwR3JvdXBEaW1lbnNpb25zOiBXcmFwR3JvdXBEaW1lbnNpb25zO1xyXG5cclxuXHRwcm90ZWN0ZWQgcmVzZXRXcmFwR3JvdXBEaW1lbnNpb25zKCk6IHZvaWQge1xyXG5cdFx0Y29uc3Qgb2xkV3JhcEdyb3VwRGltZW5zaW9ucyA9IHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucztcclxuXHRcdHRoaXMuaW52YWxpZGF0ZUFsbENhY2hlZE1lYXN1cmVtZW50cygpO1xyXG5cclxuXHRcdGlmICghdGhpcy5lbmFibGVVbmVxdWFsQ2hpbGRyZW5TaXplcyB8fCAhb2xkV3JhcEdyb3VwRGltZW5zaW9ucyB8fCBvbGRXcmFwR3JvdXBEaW1lbnNpb25zLm51bWJlck9mS25vd25XcmFwR3JvdXBDaGlsZFNpemVzID09PSAwKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHRjb25zdCBpdGVtc1BlcldyYXBHcm91cDogbnVtYmVyID0gdGhpcy5jb3VudEl0ZW1zUGVyV3JhcEdyb3VwKCk7XHJcblx0XHRmb3IgKGxldCB3cmFwR3JvdXBJbmRleCA9IDA7IHdyYXBHcm91cEluZGV4IDwgb2xkV3JhcEdyb3VwRGltZW5zaW9ucy5tYXhDaGlsZFNpemVQZXJXcmFwR3JvdXAubGVuZ3RoOyArK3dyYXBHcm91cEluZGV4KSB7XHJcblx0XHRcdGNvbnN0IG9sZFdyYXBHcm91cERpbWVuc2lvbjogV3JhcEdyb3VwRGltZW5zaW9uID0gb2xkV3JhcEdyb3VwRGltZW5zaW9ucy5tYXhDaGlsZFNpemVQZXJXcmFwR3JvdXBbd3JhcEdyb3VwSW5kZXhdO1xyXG5cdFx0XHRpZiAoIW9sZFdyYXBHcm91cERpbWVuc2lvbiB8fCAhb2xkV3JhcEdyb3VwRGltZW5zaW9uLml0ZW1zIHx8ICFvbGRXcmFwR3JvdXBEaW1lbnNpb24uaXRlbXMubGVuZ3RoKSB7XHJcblx0XHRcdFx0Y29udGludWU7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGlmIChvbGRXcmFwR3JvdXBEaW1lbnNpb24uaXRlbXMubGVuZ3RoICE9PSBpdGVtc1BlcldyYXBHcm91cCkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0bGV0IGl0ZW1zQ2hhbmdlZCA9IGZhbHNlO1xyXG5cdFx0XHRjb25zdCBhcnJheVN0YXJ0SW5kZXggPSBpdGVtc1BlcldyYXBHcm91cCAqIHdyYXBHcm91cEluZGV4O1xyXG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGl0ZW1zUGVyV3JhcEdyb3VwOyArK2kpIHtcclxuXHRcdFx0XHRpZiAoIXRoaXMuY29tcGFyZUl0ZW1zKG9sZFdyYXBHcm91cERpbWVuc2lvbi5pdGVtc1tpXSwgdGhpcy5pdGVtc1thcnJheVN0YXJ0SW5kZXggKyBpXSkpIHtcclxuXHRcdFx0XHRcdGl0ZW1zQ2hhbmdlZCA9IHRydWU7XHJcblx0XHRcdFx0XHRicmVhaztcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGlmICghaXRlbXNDaGFuZ2VkKSB7XHJcblx0XHRcdFx0Kyt0aGlzLndyYXBHcm91cERpbWVuc2lvbnMubnVtYmVyT2ZLbm93bldyYXBHcm91cENoaWxkU2l6ZXM7XHJcblx0XHRcdFx0dGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLnN1bU9mS25vd25XcmFwR3JvdXBDaGlsZFdpZHRocyArPSBvbGRXcmFwR3JvdXBEaW1lbnNpb24uY2hpbGRXaWR0aCB8fCAwO1xyXG5cdFx0XHRcdHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5zdW1PZktub3duV3JhcEdyb3VwQ2hpbGRIZWlnaHRzICs9IG9sZFdyYXBHcm91cERpbWVuc2lvbi5jaGlsZEhlaWdodCB8fCAwO1xyXG5cdFx0XHRcdHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5tYXhDaGlsZFNpemVQZXJXcmFwR3JvdXBbd3JhcEdyb3VwSW5kZXhdID0gb2xkV3JhcEdyb3VwRGltZW5zaW9uO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRwcm90ZWN0ZWQgY2FsY3VsYXRlRGltZW5zaW9ucygpOiBJRGltZW5zaW9ucyB7XHJcblx0XHRjb25zdCBzY3JvbGxFbGVtZW50ID0gdGhpcy5nZXRTY3JvbGxFbGVtZW50KCk7XHJcblxyXG5cdFx0Y29uc3QgbWF4Q2FsY3VsYXRlZFNjcm9sbEJhclNpemUgPSAyNTsgLy8gTm90ZTogRm9ybXVsYSB0byBhdXRvLWNhbGN1bGF0ZSBkb2Vzbid0IHdvcmsgZm9yIFBhcmVudFNjcm9sbCwgc28gd2UgZGVmYXVsdCB0byB0aGlzIGlmIG5vdCBzZXQgYnkgY29uc3VtaW5nIGFwcGxpY2F0aW9uXHJcblx0XHR0aGlzLmNhbGN1bGF0ZWRTY3JvbGxiYXJIZWlnaHQgPSBNYXRoLm1heChNYXRoLm1pbihzY3JvbGxFbGVtZW50Lm9mZnNldEhlaWdodCAtIHNjcm9sbEVsZW1lbnQuY2xpZW50SGVpZ2h0LCBtYXhDYWxjdWxhdGVkU2Nyb2xsQmFyU2l6ZSksIHRoaXMuY2FsY3VsYXRlZFNjcm9sbGJhckhlaWdodCk7XHJcblx0XHR0aGlzLmNhbGN1bGF0ZWRTY3JvbGxiYXJXaWR0aCA9IE1hdGgubWF4KE1hdGgubWluKHNjcm9sbEVsZW1lbnQub2Zmc2V0V2lkdGggLSBzY3JvbGxFbGVtZW50LmNsaWVudFdpZHRoLCBtYXhDYWxjdWxhdGVkU2Nyb2xsQmFyU2l6ZSksIHRoaXMuY2FsY3VsYXRlZFNjcm9sbGJhcldpZHRoKTtcclxuXHJcblx0XHRsZXQgdmlld3BvcnRXaWR0aCA9IHNjcm9sbEVsZW1lbnQub2Zmc2V0V2lkdGggLSAodGhpcy5zY3JvbGxiYXJXaWR0aCB8fCB0aGlzLmNhbGN1bGF0ZWRTY3JvbGxiYXJXaWR0aCB8fCAodGhpcy5ob3Jpem9udGFsID8gMCA6IG1heENhbGN1bGF0ZWRTY3JvbGxCYXJTaXplKSk7XHJcblx0XHRsZXQgdmlld3BvcnRIZWlnaHQgPSBzY3JvbGxFbGVtZW50Lm9mZnNldEhlaWdodCAtICh0aGlzLnNjcm9sbGJhckhlaWdodCB8fCB0aGlzLmNhbGN1bGF0ZWRTY3JvbGxiYXJIZWlnaHQgfHwgKHRoaXMuaG9yaXpvbnRhbCA/IG1heENhbGN1bGF0ZWRTY3JvbGxCYXJTaXplIDogMCkpO1xyXG5cclxuXHRcdGNvbnN0IGNvbnRlbnQgPSB0aGlzLmdldENvbnRlbnQoKTtcclxuXHJcblx0XHRjb25zdCBpdGVtc1BlcldyYXBHcm91cCA9IHRoaXMuY291bnRJdGVtc1BlcldyYXBHcm91cCgpO1xyXG5cdFx0bGV0IHdyYXBHcm91cHNQZXJQYWdlO1xyXG5cclxuXHRcdGxldCBkZWZhdWx0Q2hpbGRXaWR0aDtcclxuXHRcdGxldCBkZWZhdWx0Q2hpbGRIZWlnaHQ7XHJcblxyXG5cdFx0aWYgKHRoaXMuaXNBbmd1bGFyVW5pdmVyc2FsU1NSKSB7XHJcblx0XHRcdHZpZXdwb3J0V2lkdGggPSB0aGlzLnNzclZpZXdwb3J0V2lkdGg7XHJcblx0XHRcdHZpZXdwb3J0SGVpZ2h0ID0gdGhpcy5zc3JWaWV3cG9ydEhlaWdodDtcclxuXHRcdFx0ZGVmYXVsdENoaWxkV2lkdGggPSB0aGlzLnNzckNoaWxkV2lkdGg7XHJcblx0XHRcdGRlZmF1bHRDaGlsZEhlaWdodCA9IHRoaXMuc3NyQ2hpbGRIZWlnaHQ7XHJcblx0XHRcdGNvbnN0IGl0ZW1zUGVyUm93ID0gTWF0aC5tYXgoTWF0aC5jZWlsKHZpZXdwb3J0V2lkdGggLyBkZWZhdWx0Q2hpbGRXaWR0aCksIDEpO1xyXG5cdFx0XHRjb25zdCBpdGVtc1BlckNvbCA9IE1hdGgubWF4KE1hdGguY2VpbCh2aWV3cG9ydEhlaWdodCAvIGRlZmF1bHRDaGlsZEhlaWdodCksIDEpO1xyXG5cdFx0XHR3cmFwR3JvdXBzUGVyUGFnZSA9IHRoaXMuaG9yaXpvbnRhbCA/IGl0ZW1zUGVyUm93IDogaXRlbXNQZXJDb2w7XHJcblx0XHR9XHJcblx0XHRlbHNlIGlmICghdGhpcy5lbmFibGVVbmVxdWFsQ2hpbGRyZW5TaXplcykge1xyXG5cdFx0XHRpZiAoY29udGVudC5jaGlsZHJlbi5sZW5ndGggPiAwKSB7XHJcblx0XHRcdFx0aWYgKCF0aGlzLmNoaWxkV2lkdGggfHwgIXRoaXMuY2hpbGRIZWlnaHQpIHtcclxuXHRcdFx0XHRcdGlmICghdGhpcy5taW5NZWFzdXJlZENoaWxkV2lkdGggJiYgdmlld3BvcnRXaWR0aCA+IDApIHtcclxuXHRcdFx0XHRcdFx0dGhpcy5taW5NZWFzdXJlZENoaWxkV2lkdGggPSB2aWV3cG9ydFdpZHRoO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0aWYgKCF0aGlzLm1pbk1lYXN1cmVkQ2hpbGRIZWlnaHQgJiYgdmlld3BvcnRIZWlnaHQgPiAwKSB7XHJcblx0XHRcdFx0XHRcdHRoaXMubWluTWVhc3VyZWRDaGlsZEhlaWdodCA9IHZpZXdwb3J0SGVpZ2h0O1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Y29uc3QgY2hpbGQgPSBjb250ZW50LmNoaWxkcmVuWzBdO1xyXG5cdFx0XHRcdGNvbnN0IGNsaWVudFJlY3QgPSB0aGlzLmdldEVsZW1lbnRTaXplKGNoaWxkKTtcclxuXHRcdFx0XHR0aGlzLm1pbk1lYXN1cmVkQ2hpbGRXaWR0aCA9IE1hdGgubWluKHRoaXMubWluTWVhc3VyZWRDaGlsZFdpZHRoLCBjbGllbnRSZWN0LndpZHRoKTtcclxuXHRcdFx0XHR0aGlzLm1pbk1lYXN1cmVkQ2hpbGRIZWlnaHQgPSBNYXRoLm1pbih0aGlzLm1pbk1lYXN1cmVkQ2hpbGRIZWlnaHQsIGNsaWVudFJlY3QuaGVpZ2h0KTtcclxuXHJcblx0XHRcdFx0Ly8gQWRkZWQgZm9yIGdldHRpbmcgdGhlIGNoaWxkIGhlaWdodCAoZm9yIGNhcmQgdmlldywgcmV0dXJuIGFsbCB0aGUgY2xpZW50UmVjdCBvYmplY3QpLlxyXG5cdFx0XHRcdC8vIGlmICh0aGlzLl9sYXN0Q2hpbGRSZWN0ID09PSBudWxsIHx8XHJcblx0XHRcdFx0Ly8gXHQoY2xpZW50UmVjdD8uaGVpZ2h0ICE9PSAwICYmIChcclxuXHRcdFx0XHQvLyBcdFx0TWF0aC5yb3VuZCh0aGlzLl9sYXN0Q2hpbGRSZWN0Py5oZWlnaHQpICE9PSBNYXRoLnJvdW5kKGNsaWVudFJlY3Q/LmhlaWdodCkgfHwgXHJcblx0XHRcdFx0Ly8gXHRcdE1hdGgucm91bmQodGhpcy5fbGFzdENoaWxkUmVjdD8ud2lkdGgpICE9PSBNYXRoLnJvdW5kKGNsaWVudFJlY3Q/LndpZHRoKSlcclxuXHRcdFx0XHQvLyBcdCkpIHtcclxuXHRcdFx0XHQvLyBcdHRoaXMuX2xhc3RDaGlsZFJlY3QgPSBjbGllbnRSZWN0O1xyXG5cdFx0XHRcdC8vIFx0dGhpcy52c0NoaWxkUmVjdENoYW5nZS5lbWl0KGNsaWVudFJlY3QpO1xyXG5cdFx0XHRcdC8vIH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0ZGVmYXVsdENoaWxkV2lkdGggPSB0aGlzLmNoaWxkV2lkdGggfHwgdGhpcy5taW5NZWFzdXJlZENoaWxkV2lkdGggfHwgdmlld3BvcnRXaWR0aDtcclxuXHRcdFx0ZGVmYXVsdENoaWxkSGVpZ2h0ID0gdGhpcy5jaGlsZEhlaWdodCB8fCB0aGlzLm1pbk1lYXN1cmVkQ2hpbGRIZWlnaHQgfHwgdmlld3BvcnRIZWlnaHQ7XHJcblx0XHRcdGNvbnN0IGl0ZW1zUGVyUm93ID0gTWF0aC5tYXgoTWF0aC5jZWlsKHZpZXdwb3J0V2lkdGggLyBkZWZhdWx0Q2hpbGRXaWR0aCksIDEpO1xyXG5cdFx0XHRjb25zdCBpdGVtc1BlckNvbCA9IE1hdGgubWF4KE1hdGguY2VpbCh2aWV3cG9ydEhlaWdodCAvIGRlZmF1bHRDaGlsZEhlaWdodCksIDEpO1xyXG5cdFx0XHR3cmFwR3JvdXBzUGVyUGFnZSA9IHRoaXMuaG9yaXpvbnRhbCA/IGl0ZW1zUGVyUm93IDogaXRlbXNQZXJDb2w7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRsZXQgc2Nyb2xsT2Zmc2V0ID0gc2Nyb2xsRWxlbWVudFt0aGlzLl9zY3JvbGxUeXBlXSAtICh0aGlzLnByZXZpb3VzVmlld1BvcnQgPyB0aGlzLnByZXZpb3VzVmlld1BvcnQucGFkZGluZyA6IDApO1xyXG5cclxuXHRcdFx0bGV0IGFycmF5U3RhcnRJbmRleCA9IHRoaXMucHJldmlvdXNWaWV3UG9ydC5zdGFydEluZGV4V2l0aEJ1ZmZlciB8fCAwO1xyXG5cdFx0XHRsZXQgd3JhcEdyb3VwSW5kZXggPSBNYXRoLmNlaWwoYXJyYXlTdGFydEluZGV4IC8gaXRlbXNQZXJXcmFwR3JvdXApO1xyXG5cclxuXHRcdFx0bGV0IG1heFdpZHRoRm9yV3JhcEdyb3VwID0gMDtcclxuXHRcdFx0bGV0IG1heEhlaWdodEZvcldyYXBHcm91cCA9IDA7XHJcblx0XHRcdGxldCBzdW1PZlZpc2libGVNYXhXaWR0aHMgPSAwO1xyXG5cdFx0XHRsZXQgc3VtT2ZWaXNpYmxlTWF4SGVpZ2h0cyA9IDA7XHJcblx0XHRcdHdyYXBHcm91cHNQZXJQYWdlID0gMDtcclxuXHJcblx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgY29udGVudC5jaGlsZHJlbi5sZW5ndGg7ICsraSkge1xyXG5cdFx0XHRcdCsrYXJyYXlTdGFydEluZGV4O1xyXG5cdFx0XHRcdGNvbnN0IGNoaWxkID0gY29udGVudC5jaGlsZHJlbltpXTtcclxuXHRcdFx0XHRjb25zdCBjbGllbnRSZWN0ID0gdGhpcy5nZXRFbGVtZW50U2l6ZShjaGlsZCk7XHJcblxyXG5cdFx0XHRcdG1heFdpZHRoRm9yV3JhcEdyb3VwID0gTWF0aC5tYXgobWF4V2lkdGhGb3JXcmFwR3JvdXAsIGNsaWVudFJlY3Qud2lkdGgpO1xyXG5cdFx0XHRcdG1heEhlaWdodEZvcldyYXBHcm91cCA9IE1hdGgubWF4KG1heEhlaWdodEZvcldyYXBHcm91cCwgY2xpZW50UmVjdC5oZWlnaHQpO1xyXG5cclxuXHRcdFx0XHRpZiAoYXJyYXlTdGFydEluZGV4ICUgaXRlbXNQZXJXcmFwR3JvdXAgPT09IDApIHtcclxuXHRcdFx0XHRcdGNvbnN0IG9sZFZhbHVlID0gdGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLm1heENoaWxkU2l6ZVBlcldyYXBHcm91cFt3cmFwR3JvdXBJbmRleF07XHJcblx0XHRcdFx0XHRpZiAob2xkVmFsdWUpIHtcclxuXHRcdFx0XHRcdFx0LS10aGlzLndyYXBHcm91cERpbWVuc2lvbnMubnVtYmVyT2ZLbm93bldyYXBHcm91cENoaWxkU2l6ZXM7XHJcblx0XHRcdFx0XHRcdHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5zdW1PZktub3duV3JhcEdyb3VwQ2hpbGRXaWR0aHMgLT0gb2xkVmFsdWUuY2hpbGRXaWR0aCB8fCAwO1xyXG5cdFx0XHRcdFx0XHR0aGlzLndyYXBHcm91cERpbWVuc2lvbnMuc3VtT2ZLbm93bldyYXBHcm91cENoaWxkSGVpZ2h0cyAtPSBvbGRWYWx1ZS5jaGlsZEhlaWdodCB8fCAwO1xyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdCsrdGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLm51bWJlck9mS25vd25XcmFwR3JvdXBDaGlsZFNpemVzO1xyXG5cdFx0XHRcdFx0Y29uc3QgaXRlbXMgPSB0aGlzLml0ZW1zLnNsaWNlKGFycmF5U3RhcnRJbmRleCAtIGl0ZW1zUGVyV3JhcEdyb3VwLCBhcnJheVN0YXJ0SW5kZXgpO1xyXG5cdFx0XHRcdFx0dGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLm1heENoaWxkU2l6ZVBlcldyYXBHcm91cFt3cmFwR3JvdXBJbmRleF0gPSB7XHJcblx0XHRcdFx0XHRcdGNoaWxkV2lkdGg6IG1heFdpZHRoRm9yV3JhcEdyb3VwLFxyXG5cdFx0XHRcdFx0XHRjaGlsZEhlaWdodDogbWF4SGVpZ2h0Rm9yV3JhcEdyb3VwLFxyXG5cdFx0XHRcdFx0XHRpdGVtczogaXRlbXNcclxuXHRcdFx0XHRcdH07XHJcblx0XHRcdFx0XHR0aGlzLndyYXBHcm91cERpbWVuc2lvbnMuc3VtT2ZLbm93bldyYXBHcm91cENoaWxkV2lkdGhzICs9IG1heFdpZHRoRm9yV3JhcEdyb3VwO1xyXG5cdFx0XHRcdFx0dGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLnN1bU9mS25vd25XcmFwR3JvdXBDaGlsZEhlaWdodHMgKz0gbWF4SGVpZ2h0Rm9yV3JhcEdyb3VwO1xyXG5cclxuXHRcdFx0XHRcdGlmICh0aGlzLmhvcml6b250YWwpIHtcclxuXHRcdFx0XHRcdFx0bGV0IG1heFZpc2libGVXaWR0aEZvcldyYXBHcm91cCA9IE1hdGgubWluKG1heFdpZHRoRm9yV3JhcEdyb3VwLCBNYXRoLm1heCh2aWV3cG9ydFdpZHRoIC0gc3VtT2ZWaXNpYmxlTWF4V2lkdGhzLCAwKSk7XHJcblx0XHRcdFx0XHRcdGlmIChzY3JvbGxPZmZzZXQgPiAwKSB7XHJcblx0XHRcdFx0XHRcdFx0Y29uc3Qgc2Nyb2xsT2Zmc2V0VG9SZW1vdmUgPSBNYXRoLm1pbihzY3JvbGxPZmZzZXQsIG1heFZpc2libGVXaWR0aEZvcldyYXBHcm91cCk7XHJcblx0XHRcdFx0XHRcdFx0bWF4VmlzaWJsZVdpZHRoRm9yV3JhcEdyb3VwIC09IHNjcm9sbE9mZnNldFRvUmVtb3ZlO1xyXG5cdFx0XHRcdFx0XHRcdHNjcm9sbE9mZnNldCAtPSBzY3JvbGxPZmZzZXRUb1JlbW92ZTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdFx0c3VtT2ZWaXNpYmxlTWF4V2lkdGhzICs9IG1heFZpc2libGVXaWR0aEZvcldyYXBHcm91cDtcclxuXHRcdFx0XHRcdFx0aWYgKG1heFZpc2libGVXaWR0aEZvcldyYXBHcm91cCA+IDAgJiYgdmlld3BvcnRXaWR0aCA+PSBzdW1PZlZpc2libGVNYXhXaWR0aHMpIHtcclxuXHRcdFx0XHRcdFx0XHQrK3dyYXBHcm91cHNQZXJQYWdlO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRsZXQgbWF4VmlzaWJsZUhlaWdodEZvcldyYXBHcm91cCA9IE1hdGgubWluKG1heEhlaWdodEZvcldyYXBHcm91cCwgTWF0aC5tYXgodmlld3BvcnRIZWlnaHQgLSBzdW1PZlZpc2libGVNYXhIZWlnaHRzLCAwKSk7XHJcblx0XHRcdFx0XHRcdGlmIChzY3JvbGxPZmZzZXQgPiAwKSB7XHJcblx0XHRcdFx0XHRcdFx0Y29uc3Qgc2Nyb2xsT2Zmc2V0VG9SZW1vdmUgPSBNYXRoLm1pbihzY3JvbGxPZmZzZXQsIG1heFZpc2libGVIZWlnaHRGb3JXcmFwR3JvdXApO1xyXG5cdFx0XHRcdFx0XHRcdG1heFZpc2libGVIZWlnaHRGb3JXcmFwR3JvdXAgLT0gc2Nyb2xsT2Zmc2V0VG9SZW1vdmU7XHJcblx0XHRcdFx0XHRcdFx0c2Nyb2xsT2Zmc2V0IC09IHNjcm9sbE9mZnNldFRvUmVtb3ZlO1xyXG5cdFx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0XHRzdW1PZlZpc2libGVNYXhIZWlnaHRzICs9IG1heFZpc2libGVIZWlnaHRGb3JXcmFwR3JvdXA7XHJcblx0XHRcdFx0XHRcdGlmIChtYXhWaXNpYmxlSGVpZ2h0Rm9yV3JhcEdyb3VwID4gMCAmJiB2aWV3cG9ydEhlaWdodCA+PSBzdW1PZlZpc2libGVNYXhIZWlnaHRzKSB7XHJcblx0XHRcdFx0XHRcdFx0Kyt3cmFwR3JvdXBzUGVyUGFnZTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdCsrd3JhcEdyb3VwSW5kZXg7XHJcblxyXG5cdFx0XHRcdFx0bWF4V2lkdGhGb3JXcmFwR3JvdXAgPSAwO1xyXG5cdFx0XHRcdFx0bWF4SGVpZ2h0Rm9yV3JhcEdyb3VwID0gMDtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGNvbnN0IGF2ZXJhZ2VDaGlsZFdpZHRoID0gdGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLnN1bU9mS25vd25XcmFwR3JvdXBDaGlsZFdpZHRocyAvIHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5udW1iZXJPZktub3duV3JhcEdyb3VwQ2hpbGRTaXplcztcclxuXHRcdFx0Y29uc3QgYXZlcmFnZUNoaWxkSGVpZ2h0ID0gdGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLnN1bU9mS25vd25XcmFwR3JvdXBDaGlsZEhlaWdodHMgLyB0aGlzLndyYXBHcm91cERpbWVuc2lvbnMubnVtYmVyT2ZLbm93bldyYXBHcm91cENoaWxkU2l6ZXM7XHJcblx0XHRcdGRlZmF1bHRDaGlsZFdpZHRoID0gdGhpcy5jaGlsZFdpZHRoIHx8IGF2ZXJhZ2VDaGlsZFdpZHRoIHx8IHZpZXdwb3J0V2lkdGg7XHJcblx0XHRcdGRlZmF1bHRDaGlsZEhlaWdodCA9IHRoaXMuY2hpbGRIZWlnaHQgfHwgYXZlcmFnZUNoaWxkSGVpZ2h0IHx8IHZpZXdwb3J0SGVpZ2h0O1xyXG5cclxuXHRcdFx0aWYgKHRoaXMuaG9yaXpvbnRhbCkge1xyXG5cdFx0XHRcdGlmICh2aWV3cG9ydFdpZHRoID4gc3VtT2ZWaXNpYmxlTWF4V2lkdGhzKSB7XHJcblx0XHRcdFx0XHR3cmFwR3JvdXBzUGVyUGFnZSArPSBNYXRoLmNlaWwoKHZpZXdwb3J0V2lkdGggLSBzdW1PZlZpc2libGVNYXhXaWR0aHMpIC8gZGVmYXVsdENoaWxkV2lkdGgpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRpZiAodmlld3BvcnRIZWlnaHQgPiBzdW1PZlZpc2libGVNYXhIZWlnaHRzKSB7XHJcblx0XHRcdFx0XHR3cmFwR3JvdXBzUGVyUGFnZSArPSBNYXRoLmNlaWwoKHZpZXdwb3J0SGVpZ2h0IC0gc3VtT2ZWaXNpYmxlTWF4SGVpZ2h0cykgLyBkZWZhdWx0Q2hpbGRIZWlnaHQpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdGNvbnN0IGl0ZW1Db3VudCA9IHRoaXMuaXRlbXMubGVuZ3RoO1xyXG5cdFx0Y29uc3QgaXRlbXNQZXJQYWdlID0gaXRlbXNQZXJXcmFwR3JvdXAgKiB3cmFwR3JvdXBzUGVyUGFnZTtcclxuXHRcdGNvbnN0IHBhZ2VDb3VudF9mcmFjdGlvbmFsID0gaXRlbUNvdW50IC8gaXRlbXNQZXJQYWdlO1xyXG5cdFx0Y29uc3QgbnVtYmVyT2ZXcmFwR3JvdXBzID0gTWF0aC5jZWlsKGl0ZW1Db3VudCAvIGl0ZW1zUGVyV3JhcEdyb3VwKTtcclxuXHJcblx0XHRsZXQgc2Nyb2xsTGVuZ3RoID0gMDtcclxuXHJcblx0XHRjb25zdCBkZWZhdWx0U2Nyb2xsTGVuZ3RoUGVyV3JhcEdyb3VwID0gdGhpcy5ob3Jpem9udGFsID8gZGVmYXVsdENoaWxkV2lkdGggOiBkZWZhdWx0Q2hpbGRIZWlnaHQ7XHJcblx0XHRpZiAodGhpcy5lbmFibGVVbmVxdWFsQ2hpbGRyZW5TaXplcykge1xyXG5cdFx0XHRsZXQgbnVtVW5rbm93bkNoaWxkU2l6ZXMgPSAwO1xyXG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IG51bWJlck9mV3JhcEdyb3VwczsgKytpKSB7XHJcblx0XHRcdFx0Y29uc3QgY2hpbGRTaXplID0gdGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLm1heENoaWxkU2l6ZVBlcldyYXBHcm91cFtpXSAmJiB0aGlzLndyYXBHcm91cERpbWVuc2lvbnMubWF4Q2hpbGRTaXplUGVyV3JhcEdyb3VwW2ldW3RoaXMuX2NoaWxkU2Nyb2xsRGltXTtcclxuXHRcdFx0XHRpZiAoY2hpbGRTaXplKSB7XHJcblx0XHRcdFx0XHRzY3JvbGxMZW5ndGggKz0gY2hpbGRTaXplO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHQrK251bVVua25vd25DaGlsZFNpemVzO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0c2Nyb2xsTGVuZ3RoICs9IE1hdGgucm91bmQobnVtVW5rbm93bkNoaWxkU2l6ZXMgKiBkZWZhdWx0U2Nyb2xsTGVuZ3RoUGVyV3JhcEdyb3VwKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHNjcm9sbExlbmd0aCA9IG51bWJlck9mV3JhcEdyb3VwcyAqIGRlZmF1bHRTY3JvbGxMZW5ndGhQZXJXcmFwR3JvdXA7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKHRoaXMuaGVhZGVyRWxlbWVudFJlZikge1xyXG5cdFx0XHRzY3JvbGxMZW5ndGggKz0gdGhpcy5oZWFkZXJFbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuY2xpZW50SGVpZ2h0O1xyXG5cdFx0fVxyXG5cclxuXHRcdGNvbnN0IHZpZXdwb3J0TGVuZ3RoID0gdGhpcy5ob3Jpem9udGFsID8gdmlld3BvcnRXaWR0aCA6IHZpZXdwb3J0SGVpZ2h0O1xyXG5cdFx0Y29uc3QgbWF4U2Nyb2xsUG9zaXRpb24gPSBNYXRoLm1heChzY3JvbGxMZW5ndGggLSB2aWV3cG9ydExlbmd0aCwgMCk7XHJcblxyXG5cdFx0cmV0dXJuIHtcclxuXHRcdFx0Y2hpbGRIZWlnaHQ6IGRlZmF1bHRDaGlsZEhlaWdodCxcclxuXHRcdFx0Y2hpbGRXaWR0aDogZGVmYXVsdENoaWxkV2lkdGgsXHJcblx0XHRcdGl0ZW1Db3VudDogaXRlbUNvdW50LFxyXG5cdFx0XHRpdGVtc1BlclBhZ2U6IGl0ZW1zUGVyUGFnZSxcclxuXHRcdFx0aXRlbXNQZXJXcmFwR3JvdXA6IGl0ZW1zUGVyV3JhcEdyb3VwLFxyXG5cdFx0XHRtYXhTY3JvbGxQb3NpdGlvbjogbWF4U2Nyb2xsUG9zaXRpb24sXHJcblx0XHRcdHBhZ2VDb3VudF9mcmFjdGlvbmFsOiBwYWdlQ291bnRfZnJhY3Rpb25hbCxcclxuXHRcdFx0c2Nyb2xsTGVuZ3RoOiBzY3JvbGxMZW5ndGgsXHJcblx0XHRcdHZpZXdwb3J0TGVuZ3RoOiB2aWV3cG9ydExlbmd0aCxcclxuXHRcdFx0d3JhcEdyb3Vwc1BlclBhZ2U6IHdyYXBHcm91cHNQZXJQYWdlLFxyXG5cdFx0fTtcclxuXHR9XHJcblxyXG5cdHByb3RlY3RlZCBjYWNoZWRQYWdlU2l6ZSA9IDA7XHJcblx0cHJvdGVjdGVkIHByZXZpb3VzU2Nyb2xsTnVtYmVyRWxlbWVudHMgPSAwO1xyXG5cclxuXHRwcm90ZWN0ZWQgY2FsY3VsYXRlUGFkZGluZyhhcnJheVN0YXJ0SW5kZXhXaXRoQnVmZmVyOiBudW1iZXIsIGRpbWVuc2lvbnM6IElEaW1lbnNpb25zKTogbnVtYmVyIHtcclxuXHRcdGlmIChkaW1lbnNpb25zLml0ZW1Db3VudCA9PT0gMCkge1xyXG5cdFx0XHRyZXR1cm4gMDtcclxuXHRcdH1cclxuXHJcblx0XHRjb25zdCBkZWZhdWx0U2Nyb2xsTGVuZ3RoUGVyV3JhcEdyb3VwID0gZGltZW5zaW9uc1t0aGlzLl9jaGlsZFNjcm9sbERpbV07XHJcblx0XHRjb25zdCBzdGFydGluZ1dyYXBHcm91cEluZGV4ID0gTWF0aC5mbG9vcihhcnJheVN0YXJ0SW5kZXhXaXRoQnVmZmVyIC8gZGltZW5zaW9ucy5pdGVtc1BlcldyYXBHcm91cCkgfHwgMDtcclxuXHJcblx0XHRpZiAoIXRoaXMuZW5hYmxlVW5lcXVhbENoaWxkcmVuU2l6ZXMpIHtcclxuXHRcdFx0cmV0dXJuIGRlZmF1bHRTY3JvbGxMZW5ndGhQZXJXcmFwR3JvdXAgKiBzdGFydGluZ1dyYXBHcm91cEluZGV4O1xyXG5cdFx0fVxyXG5cclxuXHRcdGxldCBudW1Vbmtub3duQ2hpbGRTaXplcyA9IDA7XHJcblx0XHRsZXQgcmVzdWx0ID0gMDtcclxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgc3RhcnRpbmdXcmFwR3JvdXBJbmRleDsgKytpKSB7XHJcblx0XHRcdGNvbnN0IGNoaWxkU2l6ZSA9IHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5tYXhDaGlsZFNpemVQZXJXcmFwR3JvdXBbaV0gJiYgdGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLm1heENoaWxkU2l6ZVBlcldyYXBHcm91cFtpXVt0aGlzLl9jaGlsZFNjcm9sbERpbV07XHJcblx0XHRcdGlmIChjaGlsZFNpemUpIHtcclxuXHRcdFx0XHRyZXN1bHQgKz0gY2hpbGRTaXplO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdCsrbnVtVW5rbm93bkNoaWxkU2l6ZXM7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdHJlc3VsdCArPSBNYXRoLnJvdW5kKG51bVVua25vd25DaGlsZFNpemVzICogZGVmYXVsdFNjcm9sbExlbmd0aFBlcldyYXBHcm91cCk7XHJcblxyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHByb3RlY3RlZCBjYWxjdWxhdGVQYWdlSW5mbyhzY3JvbGxQb3NpdGlvbjogbnVtYmVyLCBkaW1lbnNpb25zOiBJRGltZW5zaW9ucyk6IElQYWdlSW5mbyB7XHJcblx0XHRsZXQgc2Nyb2xsUGVyY2VudGFnZSA9IDA7XHJcblx0XHRpZiAodGhpcy5lbmFibGVVbmVxdWFsQ2hpbGRyZW5TaXplcykge1xyXG5cdFx0XHRjb25zdCBudW1iZXJPZldyYXBHcm91cHMgPSBNYXRoLmNlaWwoZGltZW5zaW9ucy5pdGVtQ291bnQgLyBkaW1lbnNpb25zLml0ZW1zUGVyV3JhcEdyb3VwKTtcclxuXHRcdFx0bGV0IHRvdGFsU2Nyb2xsZWRMZW5ndGggPSAwO1xyXG5cdFx0XHRjb25zdCBkZWZhdWx0U2Nyb2xsTGVuZ3RoUGVyV3JhcEdyb3VwID0gZGltZW5zaW9uc1t0aGlzLl9jaGlsZFNjcm9sbERpbV07XHJcblx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgbnVtYmVyT2ZXcmFwR3JvdXBzOyArK2kpIHtcclxuXHRcdFx0XHRjb25zdCBjaGlsZFNpemUgPSB0aGlzLndyYXBHcm91cERpbWVuc2lvbnMubWF4Q2hpbGRTaXplUGVyV3JhcEdyb3VwW2ldICYmIHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5tYXhDaGlsZFNpemVQZXJXcmFwR3JvdXBbaV1bdGhpcy5fY2hpbGRTY3JvbGxEaW1dO1xyXG5cdFx0XHRcdGlmIChjaGlsZFNpemUpIHtcclxuXHRcdFx0XHRcdHRvdGFsU2Nyb2xsZWRMZW5ndGggKz0gY2hpbGRTaXplO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHR0b3RhbFNjcm9sbGVkTGVuZ3RoICs9IGRlZmF1bHRTY3JvbGxMZW5ndGhQZXJXcmFwR3JvdXA7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRpZiAoc2Nyb2xsUG9zaXRpb24gPCB0b3RhbFNjcm9sbGVkTGVuZ3RoKSB7XHJcblx0XHRcdFx0XHRzY3JvbGxQZXJjZW50YWdlID0gaSAvIG51bWJlck9mV3JhcEdyb3VwcztcclxuXHRcdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0c2Nyb2xsUGVyY2VudGFnZSA9IHNjcm9sbFBvc2l0aW9uIC8gZGltZW5zaW9ucy5zY3JvbGxMZW5ndGg7XHJcblx0XHR9XHJcblxyXG5cdFx0Y29uc3Qgc3RhcnRpbmdBcnJheUluZGV4X2ZyYWN0aW9uYWwgPSBNYXRoLm1pbihNYXRoLm1heChzY3JvbGxQZXJjZW50YWdlICogZGltZW5zaW9ucy5wYWdlQ291bnRfZnJhY3Rpb25hbCwgMCksIGRpbWVuc2lvbnMucGFnZUNvdW50X2ZyYWN0aW9uYWwpICogZGltZW5zaW9ucy5pdGVtc1BlclBhZ2U7XHJcblxyXG5cdFx0Y29uc3QgbWF4U3RhcnQgPSBkaW1lbnNpb25zLml0ZW1Db3VudCAtIGRpbWVuc2lvbnMuaXRlbXNQZXJQYWdlIC0gMTtcclxuXHRcdGxldCBhcnJheVN0YXJ0SW5kZXggPSBNYXRoLm1pbihNYXRoLmZsb29yKHN0YXJ0aW5nQXJyYXlJbmRleF9mcmFjdGlvbmFsKSwgbWF4U3RhcnQpO1xyXG5cdFx0YXJyYXlTdGFydEluZGV4IC09IGFycmF5U3RhcnRJbmRleCAlIGRpbWVuc2lvbnMuaXRlbXNQZXJXcmFwR3JvdXA7IC8vIHJvdW5kIGRvd24gdG8gc3RhcnQgb2Ygd3JhcEdyb3VwXHJcblxyXG5cdFx0aWYgKHRoaXMuc3RyaXBlZFRhYmxlKSB7XHJcblx0XHRcdGNvbnN0IGJ1ZmZlckJvdW5kYXJ5ID0gMiAqIGRpbWVuc2lvbnMuaXRlbXNQZXJXcmFwR3JvdXA7XHJcblx0XHRcdGlmIChhcnJheVN0YXJ0SW5kZXggJSBidWZmZXJCb3VuZGFyeSAhPT0gMCkge1xyXG5cdFx0XHRcdGFycmF5U3RhcnRJbmRleCA9IE1hdGgubWF4KGFycmF5U3RhcnRJbmRleCAtIGFycmF5U3RhcnRJbmRleCAlIGJ1ZmZlckJvdW5kYXJ5LCAwKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdGxldCBhcnJheUVuZEluZGV4ID0gTWF0aC5jZWlsKHN0YXJ0aW5nQXJyYXlJbmRleF9mcmFjdGlvbmFsKSArIGRpbWVuc2lvbnMuaXRlbXNQZXJQYWdlIC0gMTtcclxuXHRcdGNvbnN0IGVuZEluZGV4V2l0aGluV3JhcEdyb3VwID0gKGFycmF5RW5kSW5kZXggKyAxKSAlIGRpbWVuc2lvbnMuaXRlbXNQZXJXcmFwR3JvdXA7XHJcblx0XHRpZiAoZW5kSW5kZXhXaXRoaW5XcmFwR3JvdXAgPiAwKSB7XHJcblx0XHRcdGFycmF5RW5kSW5kZXggKz0gZGltZW5zaW9ucy5pdGVtc1BlcldyYXBHcm91cCAtIGVuZEluZGV4V2l0aGluV3JhcEdyb3VwOyAvLyByb3VuZCB1cCB0byBlbmQgb2Ygd3JhcEdyb3VwXHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKGlzTmFOKGFycmF5U3RhcnRJbmRleCkpIHtcclxuXHRcdFx0YXJyYXlTdGFydEluZGV4ID0gMDtcclxuXHRcdH1cclxuXHRcdGlmIChpc05hTihhcnJheUVuZEluZGV4KSkge1xyXG5cdFx0XHRhcnJheUVuZEluZGV4ID0gMDtcclxuXHRcdH1cclxuXHJcblx0XHRhcnJheVN0YXJ0SW5kZXggPSBNYXRoLm1pbihNYXRoLm1heChhcnJheVN0YXJ0SW5kZXgsIDApLCBkaW1lbnNpb25zLml0ZW1Db3VudCAtIDEpO1xyXG5cdFx0YXJyYXlFbmRJbmRleCA9IE1hdGgubWluKE1hdGgubWF4KGFycmF5RW5kSW5kZXgsIDApLCBkaW1lbnNpb25zLml0ZW1Db3VudCAtIDEpO1xyXG5cclxuXHRcdGNvbnN0IGJ1ZmZlclNpemUgPSB0aGlzLmJ1ZmZlckFtb3VudCAqIGRpbWVuc2lvbnMuaXRlbXNQZXJXcmFwR3JvdXA7XHJcblx0XHRjb25zdCBzdGFydEluZGV4V2l0aEJ1ZmZlciA9IE1hdGgubWluKE1hdGgubWF4KGFycmF5U3RhcnRJbmRleCAtIGJ1ZmZlclNpemUsIDApLCBkaW1lbnNpb25zLml0ZW1Db3VudCAtIDEpO1xyXG5cdFx0Y29uc3QgZW5kSW5kZXhXaXRoQnVmZmVyID0gTWF0aC5taW4oTWF0aC5tYXgoYXJyYXlFbmRJbmRleCArIGJ1ZmZlclNpemUsIDApLCBkaW1lbnNpb25zLml0ZW1Db3VudCAtIDEpO1xyXG5cclxuXHRcdHJldHVybiB7XHJcblx0XHRcdHN0YXJ0SW5kZXg6IGFycmF5U3RhcnRJbmRleCxcclxuXHRcdFx0ZW5kSW5kZXg6IGFycmF5RW5kSW5kZXgsXHJcblx0XHRcdHN0YXJ0SW5kZXhXaXRoQnVmZmVyOiBzdGFydEluZGV4V2l0aEJ1ZmZlcixcclxuXHRcdFx0ZW5kSW5kZXhXaXRoQnVmZmVyOiBlbmRJbmRleFdpdGhCdWZmZXIsXHJcblx0XHRcdHNjcm9sbFN0YXJ0UG9zaXRpb246IHNjcm9sbFBvc2l0aW9uLFxyXG5cdFx0XHRzY3JvbGxFbmRQb3NpdGlvbjogc2Nyb2xsUG9zaXRpb24gKyBkaW1lbnNpb25zLnZpZXdwb3J0TGVuZ3RoLFxyXG5cdFx0XHRtYXhTY3JvbGxQb3NpdGlvbjogZGltZW5zaW9ucy5tYXhTY3JvbGxQb3NpdGlvblxyXG5cdFx0fTtcclxuXHR9XHJcblxyXG5cdHByb3RlY3RlZCBjYWxjdWxhdGVWaWV3cG9ydCgpOiBJVmlld3BvcnQge1xyXG5cdFx0Y29uc3QgZGltZW5zaW9ucyA9IHRoaXMuY2FsY3VsYXRlRGltZW5zaW9ucygpO1xyXG5cdFx0Y29uc3Qgb2Zmc2V0ID0gdGhpcy5nZXRFbGVtZW50c09mZnNldCgpO1xyXG5cclxuXHRcdGxldCBzY3JvbGxTdGFydFBvc2l0aW9uID0gdGhpcy5nZXRTY3JvbGxTdGFydFBvc2l0aW9uKCk7XHJcblx0XHRpZiAoc2Nyb2xsU3RhcnRQb3NpdGlvbiA+IChkaW1lbnNpb25zLnNjcm9sbExlbmd0aCArIG9mZnNldCkgJiYgISh0aGlzLnBhcmVudFNjcm9sbCBpbnN0YW5jZW9mIFdpbmRvdykpIHtcclxuXHRcdFx0c2Nyb2xsU3RhcnRQb3NpdGlvbiA9IGRpbWVuc2lvbnMuc2Nyb2xsTGVuZ3RoO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0c2Nyb2xsU3RhcnRQb3NpdGlvbiAtPSBvZmZzZXQ7XHJcblx0XHR9XHJcblx0XHRzY3JvbGxTdGFydFBvc2l0aW9uID0gTWF0aC5tYXgoMCwgc2Nyb2xsU3RhcnRQb3NpdGlvbik7XHJcblxyXG5cdFx0Y29uc3QgcGFnZUluZm8gPSB0aGlzLmNhbGN1bGF0ZVBhZ2VJbmZvKHNjcm9sbFN0YXJ0UG9zaXRpb24sIGRpbWVuc2lvbnMpO1xyXG5cdFx0Y29uc3QgbmV3UGFkZGluZyA9IHRoaXMuY2FsY3VsYXRlUGFkZGluZyhwYWdlSW5mby5zdGFydEluZGV4V2l0aEJ1ZmZlciwgZGltZW5zaW9ucyk7XHJcblx0XHRjb25zdCBuZXdTY3JvbGxMZW5ndGggPSBkaW1lbnNpb25zLnNjcm9sbExlbmd0aDtcclxuXHJcblx0XHRyZXR1cm4ge1xyXG5cdFx0XHRzdGFydEluZGV4OiBwYWdlSW5mby5zdGFydEluZGV4LFxyXG5cdFx0XHRlbmRJbmRleDogcGFnZUluZm8uZW5kSW5kZXgsXHJcblx0XHRcdHN0YXJ0SW5kZXhXaXRoQnVmZmVyOiBwYWdlSW5mby5zdGFydEluZGV4V2l0aEJ1ZmZlcixcclxuXHRcdFx0ZW5kSW5kZXhXaXRoQnVmZmVyOiBwYWdlSW5mby5lbmRJbmRleFdpdGhCdWZmZXIsXHJcblx0XHRcdHBhZGRpbmc6IE1hdGgucm91bmQobmV3UGFkZGluZyksXHJcblx0XHRcdHNjcm9sbExlbmd0aDogTWF0aC5yb3VuZChuZXdTY3JvbGxMZW5ndGgpLFxyXG5cdFx0XHRzY3JvbGxTdGFydFBvc2l0aW9uOiBwYWdlSW5mby5zY3JvbGxTdGFydFBvc2l0aW9uLFxyXG5cdFx0XHRzY3JvbGxFbmRQb3NpdGlvbjogcGFnZUluZm8uc2Nyb2xsRW5kUG9zaXRpb24sXHJcblx0XHRcdG1heFNjcm9sbFBvc2l0aW9uOiBwYWdlSW5mby5tYXhTY3JvbGxQb3NpdGlvblxyXG5cdFx0fTtcclxuXHR9XHJcbn1cclxuXHJcbkBOZ01vZHVsZSh7XHJcblx0ZXhwb3J0czogW1ZpcnR1YWxTY3JvbGxlckNvbXBvbmVudF0sXHJcblx0ZGVjbGFyYXRpb25zOiBbVmlydHVhbFNjcm9sbGVyQ29tcG9uZW50XSxcclxuXHRpbXBvcnRzOiBbQ29tbW9uTW9kdWxlXSxcclxuXHRwcm92aWRlcnM6IFtcclxuXHRcdHtcclxuXHRcdFx0cHJvdmlkZTogJ3ZpcnR1YWwtc2Nyb2xsZXItZGVmYXVsdC1vcHRpb25zJyxcclxuXHRcdFx0dXNlRmFjdG9yeTogVklSVFVBTF9TQ1JPTExFUl9ERUZBVUxUX09QVElPTlNfRkFDVE9SWVxyXG5cdFx0fVxyXG5cdF1cclxufSlcclxuZXhwb3J0IGNsYXNzIFZpcnR1YWxTY3JvbGxlck1vZHVsZSB7IH0iXX0=
|