@spartan-ng/brain 0.0.1-alpha.373 → 0.0.1-alpha.379
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/accordion/README.md +3 -0
- package/accordion/index.d.ts +13 -0
- package/accordion/lib/brn-accordion-content.component.d.ts +15 -0
- package/accordion/lib/brn-accordion.directive.d.ts +47 -0
- package/alert-dialog/README.md +3 -0
- package/alert-dialog/index.d.ts +25 -0
- package/alert-dialog/lib/brn-alert-dialog-content.directive.d.ts +6 -0
- package/alert-dialog/lib/brn-alert-dialog-description.directive.d.ts +6 -0
- package/alert-dialog/lib/brn-alert-dialog-overlay.component.d.ts +6 -0
- package/alert-dialog/lib/brn-alert-dialog-title.directive.d.ts +6 -0
- package/alert-dialog/lib/brn-alert-dialog-trigger.directive.d.ts +8 -0
- package/alert-dialog/lib/brn-alert-dialog.component.d.ts +7 -0
- package/avatar/README.md +3 -0
- package/avatar/index.d.ts +17 -0
- package/avatar/lib/brn-avatar.component.d.ts +7 -0
- package/avatar/lib/fallback/brn-avatar-fallback.directive.d.ts +11 -0
- package/avatar/lib/fallback/index.d.ts +1 -0
- package/avatar/lib/image/brn-avatar-image.directive.d.ts +9 -0
- package/avatar/lib/image/index.d.ts +1 -0
- package/avatar/lib/util/hex-color-for.d.ts +1 -0
- package/avatar/lib/util/index.d.ts +3 -0
- package/avatar/lib/util/initials.pipe.d.ts +7 -0
- package/avatar/lib/util/is-bright.d.ts +1 -0
- package/calendar/README.md +3 -0
- package/calendar/index.d.ts +36 -0
- package/calendar/lib/brn-calendar-cell-button.directive.d.ts +59 -0
- package/calendar/lib/brn-calendar-cell.directive.d.ts +5 -0
- package/calendar/lib/brn-calendar-grid.directive.d.ts +7 -0
- package/calendar/lib/brn-calendar-header.directive.d.ts +7 -0
- package/calendar/lib/brn-calendar-next-button.directive.d.ts +13 -0
- package/calendar/lib/brn-calendar-previous-button.directive.d.ts +13 -0
- package/calendar/lib/brn-calendar-week.directive.d.ts +25 -0
- package/calendar/lib/brn-calendar-weekday.directive.d.ts +25 -0
- package/calendar/lib/brn-calendar.directive.d.ts +55 -0
- package/calendar/lib/brn-calendar.token.d.ts +8 -0
- package/calendar/lib/i18n/calendar-i18n.d.ts +17 -0
- package/checkbox/lib/brn-checkbox.component.d.ts +1 -1
- package/collapsible/README.md +3 -0
- package/collapsible/index.d.ts +16 -0
- package/collapsible/lib/brn-collapsible-content.component.d.ts +19 -0
- package/collapsible/lib/brn-collapsible-trigger.directive.d.ts +12 -0
- package/collapsible/lib/brn-collapsible.component.d.ts +11 -0
- package/command/README.md +3 -0
- package/command/index.d.ts +33 -0
- package/command/lib/brn-command-empty.directive.d.ts +6 -0
- package/command/lib/brn-command-group.component.d.ts +6 -0
- package/command/lib/brn-command-input.directive.d.ts +6 -0
- package/command/lib/brn-command-item.directive.d.ts +6 -0
- package/command/lib/brn-command-list.component.d.ts +6 -0
- package/command/lib/brn-command-loader.directive.d.ts +6 -0
- package/command/lib/brn-command-separator.component.d.ts +6 -0
- package/command/lib/brn-command.component.d.ts +6 -0
- package/date-time/README.md +3 -0
- package/date-time/index.d.ts +2 -0
- package/date-time/lib/date-adapter.d.ts +176 -0
- package/date-time/lib/native-date-adapter.d.ts +103 -0
- package/date-time-luxon/README.md +3 -0
- package/date-time-luxon/index.d.ts +1 -0
- package/date-time-luxon/lib/date-adapter.d.ts +29 -0
- package/dialog/README.md +3 -0
- package/dialog/index.d.ts +33 -0
- package/dialog/lib/brn-dialog-close.directive.d.ts +10 -0
- package/dialog/lib/brn-dialog-content.directive.d.ts +12 -0
- package/dialog/lib/brn-dialog-description.directive.d.ts +8 -0
- package/dialog/lib/brn-dialog-options.d.ts +26 -0
- package/dialog/lib/brn-dialog-overlay.component.d.ts +8 -0
- package/dialog/lib/brn-dialog-ref.d.ts +24 -0
- package/dialog/lib/brn-dialog-state.d.ts +1 -0
- package/dialog/lib/brn-dialog-title.directive.d.ts +8 -0
- package/dialog/lib/brn-dialog-trigger.directive.d.ts +16 -0
- package/dialog/lib/brn-dialog-utils.d.ts +1 -0
- package/dialog/lib/brn-dialog.component.d.ts +56 -0
- package/dialog/lib/brn-dialog.service.d.ts +22 -0
- package/esm2022/accordion/index.mjs +31 -0
- package/esm2022/accordion/lib/brn-accordion-content.component.mjs +50 -0
- package/esm2022/accordion/lib/brn-accordion.directive.mjs +180 -0
- package/esm2022/accordion/spartan-ng-brain-accordion.mjs +5 -0
- package/esm2022/alert-dialog/index.mjs +45 -0
- package/esm2022/alert-dialog/lib/brn-alert-dialog-content.directive.mjs +17 -0
- package/esm2022/alert-dialog/lib/brn-alert-dialog-description.directive.mjs +18 -0
- package/esm2022/alert-dialog/lib/brn-alert-dialog-overlay.component.mjs +20 -0
- package/esm2022/alert-dialog/lib/brn-alert-dialog-title.directive.mjs +18 -0
- package/esm2022/alert-dialog/lib/brn-alert-dialog-trigger.directive.mjs +27 -0
- package/esm2022/alert-dialog/lib/brn-alert-dialog.component.mjs +40 -0
- package/esm2022/alert-dialog/spartan-ng-brain-alert-dialog.mjs +5 -0
- package/esm2022/avatar/index.mjs +23 -0
- package/esm2022/avatar/lib/brn-avatar.component.mjs +31 -0
- package/esm2022/avatar/lib/fallback/brn-avatar-fallback.directive.mjs +21 -0
- package/esm2022/avatar/lib/fallback/index.mjs +2 -0
- package/esm2022/avatar/lib/image/brn-avatar-image.directive.mjs +29 -0
- package/esm2022/avatar/lib/image/index.mjs +2 -0
- package/esm2022/avatar/lib/util/hex-color-for.mjs +22 -0
- package/esm2022/avatar/lib/util/index.mjs +4 -0
- package/esm2022/avatar/lib/util/initials.pipe.mjs +27 -0
- package/esm2022/avatar/lib/util/is-bright.mjs +12 -0
- package/esm2022/avatar/spartan-ng-brain-avatar.mjs +5 -0
- package/esm2022/calendar/index.mjs +62 -0
- package/esm2022/calendar/lib/brn-calendar-cell-button.directive.mjs +160 -0
- package/esm2022/calendar/lib/brn-calendar-cell.directive.mjs +17 -0
- package/esm2022/calendar/lib/brn-calendar-grid.directive.mjs +21 -0
- package/esm2022/calendar/lib/brn-calendar-header.directive.mjs +22 -0
- package/esm2022/calendar/lib/brn-calendar-next-button.directive.mjs +42 -0
- package/esm2022/calendar/lib/brn-calendar-previous-button.directive.mjs +42 -0
- package/esm2022/calendar/lib/brn-calendar-week.directive.mjs +64 -0
- package/esm2022/calendar/lib/brn-calendar-weekday.directive.mjs +48 -0
- package/esm2022/calendar/lib/brn-calendar.directive.mjs +154 -0
- package/esm2022/calendar/lib/brn-calendar.token.mjs +12 -0
- package/esm2022/calendar/lib/i18n/calendar-i18n.mjs +33 -0
- package/esm2022/calendar/spartan-ng-brain-calendar.mjs +5 -0
- package/esm2022/checkbox/lib/brn-checkbox.component.mjs +1 -1
- package/esm2022/collapsible/index.mjs +30 -0
- package/esm2022/collapsible/lib/brn-collapsible-content.component.mjs +61 -0
- package/esm2022/collapsible/lib/brn-collapsible-trigger.directive.mjs +35 -0
- package/esm2022/collapsible/lib/brn-collapsible.component.mjs +33 -0
- package/esm2022/collapsible/spartan-ng-brain-collapsible.mjs +5 -0
- package/esm2022/command/index.mjs +64 -0
- package/esm2022/command/lib/brn-command-empty.directive.mjs +29 -0
- package/esm2022/command/lib/brn-command-group.component.mjs +45 -0
- package/esm2022/command/lib/brn-command-input.directive.mjs +29 -0
- package/esm2022/command/lib/brn-command-item.directive.mjs +36 -0
- package/esm2022/command/lib/brn-command-list.component.mjs +35 -0
- package/esm2022/command/lib/brn-command-loader.directive.mjs +29 -0
- package/esm2022/command/lib/brn-command-separator.component.mjs +30 -0
- package/esm2022/command/lib/brn-command.component.mjs +21 -0
- package/esm2022/command/spartan-ng-brain-command.mjs +5 -0
- package/esm2022/date-time/index.mjs +3 -0
- package/esm2022/date-time/lib/date-adapter.mjs +16 -0
- package/esm2022/date-time/lib/native-date-adapter.mjs +155 -0
- package/esm2022/date-time/spartan-ng-brain-date-time.mjs +5 -0
- package/esm2022/date-time-luxon/index.mjs +2 -0
- package/esm2022/date-time-luxon/lib/date-adapter.mjs +85 -0
- package/esm2022/date-time-luxon/spartan-ng-brain-date-time-luxon.mjs +5 -0
- package/esm2022/dialog/index.mjs +55 -0
- package/esm2022/dialog/lib/brn-dialog-close.directive.mjs +29 -0
- package/esm2022/dialog/lib/brn-dialog-content.directive.mjs +41 -0
- package/esm2022/dialog/lib/brn-dialog-description.directive.mjs +25 -0
- package/esm2022/dialog/lib/brn-dialog-options.mjs +19 -0
- package/esm2022/dialog/lib/brn-dialog-overlay.component.mjs +29 -0
- package/esm2022/dialog/lib/brn-dialog-ref.mjs +53 -0
- package/esm2022/dialog/lib/brn-dialog-state.mjs +2 -0
- package/esm2022/dialog/lib/brn-dialog-title.directive.mjs +25 -0
- package/esm2022/dialog/lib/brn-dialog-trigger.directive.mjs +39 -0
- package/esm2022/dialog/lib/brn-dialog-utils.mjs +12 -0
- package/esm2022/dialog/lib/brn-dialog.component.mjs +208 -0
- package/esm2022/dialog/lib/brn-dialog.service.mjs +127 -0
- package/esm2022/dialog/spartan-ng-brain-dialog.mjs +5 -0
- package/esm2022/form-field/index.mjs +2 -0
- package/esm2022/form-field/lib/brn-form-field-control.mjs +14 -0
- package/esm2022/form-field/spartan-ng-brain-form-field.mjs +5 -0
- package/esm2022/forms/index.mjs +4 -0
- package/esm2022/forms/lib/control-value-accessor.mjs +2 -0
- package/esm2022/forms/lib/error-options.mjs +26 -0
- package/esm2022/forms/lib/error-state-tracker.mjs +29 -0
- package/esm2022/forms/spartan-ng-brain-forms.mjs +5 -0
- package/esm2022/hover-card/index.mjs +29 -0
- package/esm2022/hover-card/lib/brn-hover-card-content.service.mjs +205 -0
- package/esm2022/hover-card/lib/brn-hover-card.component.mjs +34 -0
- package/esm2022/hover-card/lib/createHoverObservable.mjs +19 -0
- package/esm2022/hover-card/spartan-ng-brain-hover-card.mjs +5 -0
- package/esm2022/label/index.mjs +17 -0
- package/esm2022/label/lib/brn-label.directive.mjs +49 -0
- package/esm2022/label/spartan-ng-brain-label.mjs +5 -0
- package/esm2022/menu/index.mjs +100 -0
- package/esm2022/menu/lib/brn-context-menu-trigger.directive.mjs +40 -0
- package/esm2022/menu/lib/brn-menu-align.mjs +15 -0
- package/esm2022/menu/lib/brn-menu-bar.directive.mjs +17 -0
- package/esm2022/menu/lib/brn-menu-group.directive.mjs +17 -0
- package/esm2022/menu/lib/brn-menu-item-checkbox.directive.mjs +30 -0
- package/esm2022/menu/lib/brn-menu-item-radio.directive.mjs +30 -0
- package/esm2022/menu/lib/brn-menu-item.directive.mjs +27 -0
- package/esm2022/menu/lib/brn-menu-trigger.directive.mjs +36 -0
- package/esm2022/menu/lib/brn-menu.directive.mjs +50 -0
- package/esm2022/menu/spartan-ng-brain-menu.mjs +5 -0
- package/esm2022/popover/index.mjs +35 -0
- package/esm2022/popover/lib/brn-popover-close.directive.mjs +15 -0
- package/esm2022/popover/lib/brn-popover-content.directive.mjs +17 -0
- package/esm2022/popover/lib/brn-popover-trigger.directive.mjs +37 -0
- package/esm2022/popover/lib/brn-popover.component.mjs +81 -0
- package/esm2022/popover/spartan-ng-brain-popover.mjs +5 -0
- package/esm2022/progress/index.mjs +21 -0
- package/esm2022/progress/lib/brn-progress-indicator.component.mjs +22 -0
- package/esm2022/progress/lib/brn-progress.component.mjs +61 -0
- package/esm2022/progress/lib/brn-progress.token.mjs +9 -0
- package/esm2022/progress/spartan-ng-brain-progress.mjs +5 -0
- package/esm2022/radio-group/index.mjs +20 -0
- package/esm2022/radio-group/lib/brn-radio-group.component.mjs +90 -0
- package/esm2022/radio-group/lib/brn-radio-group.token.mjs +9 -0
- package/esm2022/radio-group/lib/brn-radio.component.mjs +185 -0
- package/esm2022/radio-group/spartan-ng-brain-radio-group.mjs +5 -0
- package/esm2022/select/index.mjs +56 -0
- package/esm2022/select/lib/brn-select-content.component.mjs +204 -0
- package/esm2022/select/lib/brn-select-group.directive.mjs +19 -0
- package/esm2022/select/lib/brn-select-label.directive.mjs +23 -0
- package/esm2022/select/lib/brn-select-option.directive.mjs +65 -0
- package/esm2022/select/lib/brn-select-value.component.mjs +46 -0
- package/esm2022/select/lib/brn-select.component.mjs +358 -0
- package/esm2022/select/lib/brn-select.service.mjs +197 -0
- package/esm2022/select/spartan-ng-brain-select.mjs +5 -0
- package/esm2022/separator/index.mjs +17 -0
- package/esm2022/separator/lib/brn-separator.component.mjs +24 -0
- package/esm2022/separator/spartan-ng-brain-separator.mjs +5 -0
- package/esm2022/sheet/index.mjs +50 -0
- package/esm2022/sheet/lib/brn-sheet-close.directive.mjs +15 -0
- package/esm2022/sheet/lib/brn-sheet-content.directive.mjs +25 -0
- package/esm2022/sheet/lib/brn-sheet-description.directive.mjs +18 -0
- package/esm2022/sheet/lib/brn-sheet-overlay.component.mjs +20 -0
- package/esm2022/sheet/lib/brn-sheet-title.directive.mjs +18 -0
- package/esm2022/sheet/lib/brn-sheet-trigger.directive.mjs +26 -0
- package/esm2022/sheet/lib/brn-sheet.component.mjs +55 -0
- package/esm2022/sheet/spartan-ng-brain-sheet.mjs +5 -0
- package/esm2022/slider/index.mjs +13 -0
- package/esm2022/slider/lib/brn-slider-thumb.directive.mjs +41 -0
- package/esm2022/slider/lib/brn-slider-tick-mark.directive.mjs +37 -0
- package/esm2022/slider/lib/brn-slider-track-active-fill.directive.mjs +29 -0
- package/esm2022/slider/lib/brn-slider-track.directive.mjs +290 -0
- package/esm2022/slider/spartan-ng-brain-slider.mjs +5 -0
- package/esm2022/switch/index.mjs +20 -0
- package/esm2022/switch/lib/brn-switch-thumb.component.mjs +16 -0
- package/esm2022/switch/lib/brn-switch.component.mjs +236 -0
- package/esm2022/switch/spartan-ng-brain-switch.mjs +5 -0
- package/esm2022/table/index.mjs +47 -0
- package/esm2022/table/lib/brn-cell-def.directive.mjs +22 -0
- package/esm2022/table/lib/brn-column-def.component.mjs +82 -0
- package/esm2022/table/lib/brn-column-manager.mjs +61 -0
- package/esm2022/table/lib/brn-footer-def.directive.mjs +22 -0
- package/esm2022/table/lib/brn-header-def.directive.mjs +22 -0
- package/esm2022/table/lib/brn-paginator.directive.mjs +109 -0
- package/esm2022/table/lib/brn-table.component.mjs +169 -0
- package/esm2022/table/spartan-ng-brain-table.mjs +5 -0
- package/esm2022/tabs/index.mjs +32 -0
- package/esm2022/tabs/lib/brn-tabs-list.directive.mjs +65 -0
- package/esm2022/tabs/lib/brn-tabs-paginated-list.directive.mjs +525 -0
- package/esm2022/tabs/lib/brn-tabs-trigger.directive.mjs +134 -0
- package/esm2022/tabs/spartan-ng-brain-tabs.mjs +5 -0
- package/esm2022/toggle/index.mjs +31 -0
- package/esm2022/toggle/lib/brn-toggle-group.component.mjs +159 -0
- package/esm2022/toggle/lib/brn-toggle-group.token.mjs +9 -0
- package/esm2022/toggle/lib/brn-toggle.directive.mjs +65 -0
- package/esm2022/toggle/spartan-ng-brain-toggle.mjs +5 -0
- package/esm2022/tooltip/index.mjs +35 -0
- package/esm2022/tooltip/lib/brn-tooltip-content.component.mjs +228 -0
- package/esm2022/tooltip/lib/brn-tooltip-content.directive.mjs +22 -0
- package/esm2022/tooltip/lib/brn-tooltip-trigger.directive.mjs +689 -0
- package/esm2022/tooltip/lib/brn-tooltip.directive.mjs +15 -0
- package/esm2022/tooltip/spartan-ng-brain-tooltip.mjs +5 -0
- package/fesm2022/spartan-ng-brain-accordion.mjs +259 -0
- package/fesm2022/spartan-ng-brain-accordion.mjs.map +1 -0
- package/fesm2022/spartan-ng-brain-alert-dialog.mjs +162 -0
- package/fesm2022/spartan-ng-brain-alert-dialog.mjs.map +1 -0
- package/fesm2022/spartan-ng-brain-avatar.mjs +156 -0
- package/fesm2022/spartan-ng-brain-avatar.mjs.map +1 -0
- package/fesm2022/spartan-ng-brain-calendar.mjs +629 -0
- package/fesm2022/spartan-ng-brain-calendar.mjs.map +1 -0
- package/fesm2022/spartan-ng-brain-checkbox.mjs.map +1 -1
- package/fesm2022/spartan-ng-brain-collapsible.mjs +152 -0
- package/fesm2022/spartan-ng-brain-collapsible.mjs.map +1 -0
- package/fesm2022/spartan-ng-brain-command.mjs +284 -0
- package/fesm2022/spartan-ng-brain-command.mjs.map +1 -0
- package/fesm2022/spartan-ng-brain-date-time-luxon.mjs +92 -0
- package/fesm2022/spartan-ng-brain-date-time-luxon.mjs.map +1 -0
- package/fesm2022/spartan-ng-brain-date-time.mjs +177 -0
- package/fesm2022/spartan-ng-brain-date-time.mjs.map +1 -0
- package/fesm2022/spartan-ng-brain-dialog.mjs +617 -0
- package/fesm2022/spartan-ng-brain-dialog.mjs.map +1 -0
- package/fesm2022/spartan-ng-brain-form-field.mjs +21 -0
- package/fesm2022/spartan-ng-brain-form-field.mjs.map +1 -0
- package/fesm2022/spartan-ng-brain-forms.mjs +61 -0
- package/fesm2022/spartan-ng-brain-forms.mjs.map +1 -0
- package/fesm2022/spartan-ng-brain-hover-card.mjs +274 -0
- package/fesm2022/spartan-ng-brain-hover-card.mjs.map +1 -0
- package/fesm2022/spartan-ng-brain-label.mjs +69 -0
- package/fesm2022/spartan-ng-brain-label.mjs.map +1 -0
- package/fesm2022/spartan-ng-brain-menu.mjs +316 -0
- package/fesm2022/spartan-ng-brain-menu.mjs.map +1 -0
- package/fesm2022/spartan-ng-brain-popover.mjs +173 -0
- package/fesm2022/spartan-ng-brain-popover.mjs.map +1 -0
- package/fesm2022/spartan-ng-brain-progress.mjs +108 -0
- package/fesm2022/spartan-ng-brain-progress.mjs.map +1 -0
- package/fesm2022/spartan-ng-brain-radio-group.mjs +299 -0
- package/fesm2022/spartan-ng-brain-radio-group.mjs.map +1 -0
- package/fesm2022/spartan-ng-brain-select.mjs +928 -0
- package/fesm2022/spartan-ng-brain-select.mjs.map +1 -0
- package/fesm2022/spartan-ng-brain-separator.mjs +44 -0
- package/fesm2022/spartan-ng-brain-separator.mjs.map +1 -0
- package/fesm2022/spartan-ng-brain-sheet.mjs +197 -0
- package/fesm2022/spartan-ng-brain-sheet.mjs.map +1 -0
- package/fesm2022/spartan-ng-brain-slider.mjs +399 -0
- package/fesm2022/spartan-ng-brain-slider.mjs.map +1 -0
- package/fesm2022/spartan-ng-brain-switch.mjs +271 -0
- package/fesm2022/spartan-ng-brain-switch.mjs.map +1 -0
- package/fesm2022/spartan-ng-brain-table.mjs +506 -0
- package/fesm2022/spartan-ng-brain-table.mjs.map +1 -0
- package/fesm2022/spartan-ng-brain-tabs.mjs +748 -0
- package/fesm2022/spartan-ng-brain-tabs.mjs.map +1 -0
- package/fesm2022/spartan-ng-brain-toggle.mjs +260 -0
- package/fesm2022/spartan-ng-brain-toggle.mjs.map +1 -0
- package/fesm2022/spartan-ng-brain-tooltip.mjs +975 -0
- package/fesm2022/spartan-ng-brain-tooltip.mjs.map +1 -0
- package/form-field/README.md +3 -0
- package/form-field/index.d.ts +1 -0
- package/form-field/lib/brn-form-field-control.d.ts +11 -0
- package/forms/README.md +3 -0
- package/forms/index.d.ts +3 -0
- package/forms/lib/control-value-accessor.d.ts +2 -0
- package/forms/lib/error-options.d.ts +14 -0
- package/forms/lib/error-state-tracker.d.ts +15 -0
- package/hover-card/README.md +3 -0
- package/hover-card/index.d.ts +14 -0
- package/hover-card/lib/brn-hover-card-content.service.d.ts +65 -0
- package/hover-card/lib/brn-hover-card.component.d.ts +9 -0
- package/hover-card/lib/createHoverObservable.d.ts +4 -0
- package/label/README.md +3 -0
- package/label/index.d.ts +8 -0
- package/label/lib/brn-label.directive.d.ts +15 -0
- package/menu/README.md +3 -0
- package/menu/index.d.ts +49 -0
- package/menu/lib/brn-context-menu-trigger.directive.d.ts +13 -0
- package/menu/lib/brn-menu-align.d.ts +3 -0
- package/menu/lib/brn-menu-bar.directive.d.ts +6 -0
- package/menu/lib/brn-menu-group.directive.d.ts +6 -0
- package/menu/lib/brn-menu-item-checkbox.directive.d.ts +11 -0
- package/menu/lib/brn-menu-item-radio.directive.d.ts +11 -0
- package/menu/lib/brn-menu-item.directive.d.ts +10 -0
- package/menu/lib/brn-menu-trigger.directive.d.ts +10 -0
- package/menu/lib/brn-menu.directive.d.ts +11 -0
- package/package.json +182 -9
- package/popover/README.md +3 -0
- package/popover/index.d.ts +19 -0
- package/popover/lib/brn-popover-close.directive.d.ts +6 -0
- package/popover/lib/brn-popover-content.directive.d.ts +6 -0
- package/popover/lib/brn-popover-trigger.directive.d.ts +10 -0
- package/popover/lib/brn-popover.component.d.ts +14 -0
- package/progress/README.md +3 -0
- package/progress/index.d.ts +14 -0
- package/progress/lib/brn-progress-indicator.component.d.ts +6 -0
- package/progress/lib/brn-progress.component.d.ts +15 -0
- package/progress/lib/brn-progress.token.d.ts +4 -0
- package/radio-group/README.md +3 -0
- package/radio-group/index.d.ts +13 -0
- package/radio-group/lib/brn-radio-group.component.d.ts +57 -0
- package/radio-group/lib/brn-radio-group.token.d.ts +4 -0
- package/radio-group/lib/brn-radio.component.d.ts +58 -0
- package/select/README.md +3 -0
- package/select/index.d.ts +28 -0
- package/select/lib/brn-select-content.component.d.ts +50 -0
- package/select/lib/brn-select-group.directive.d.ts +6 -0
- package/select/lib/brn-select-label.directive.d.ts +9 -0
- package/select/lib/brn-select-option.directive.d.ts +25 -0
- package/select/lib/brn-select-value.component.d.ts +11 -0
- package/select/lib/brn-select.component.d.ts +82 -0
- package/select/lib/brn-select.service.d.ts +67 -0
- package/separator/README.md +3 -0
- package/separator/index.d.ts +8 -0
- package/separator/lib/brn-separator.component.d.ts +11 -0
- package/sheet/README.md +3 -0
- package/sheet/index.d.ts +28 -0
- package/sheet/lib/brn-sheet-close.directive.d.ts +6 -0
- package/sheet/lib/brn-sheet-content.directive.d.ts +8 -0
- package/sheet/lib/brn-sheet-description.directive.d.ts +6 -0
- package/sheet/lib/brn-sheet-overlay.component.d.ts +6 -0
- package/sheet/lib/brn-sheet-title.directive.d.ts +6 -0
- package/sheet/lib/brn-sheet-trigger.directive.d.ts +9 -0
- package/sheet/lib/brn-sheet.component.d.ts +9 -0
- package/slider/README.md +3 -0
- package/slider/index.d.ts +7 -0
- package/slider/lib/brn-slider-thumb.directive.d.ts +17 -0
- package/slider/lib/brn-slider-tick-mark.directive.d.ts +15 -0
- package/slider/lib/brn-slider-track-active-fill.directive.d.ts +10 -0
- package/slider/lib/brn-slider-track.directive.d.ts +139 -0
- package/switch/README.md +3 -0
- package/switch/index.d.ts +13 -0
- package/switch/lib/brn-switch-thumb.component.d.ts +5 -0
- package/switch/lib/brn-switch.component.d.ts +58 -0
- package/table/README.md +3 -0
- package/table/index.d.ts +26 -0
- package/table/lib/brn-cell-def.directive.d.ts +9 -0
- package/table/lib/brn-column-def.component.d.ts +18 -0
- package/table/lib/brn-column-manager.d.ts +26 -0
- package/table/lib/brn-footer-def.directive.d.ts +9 -0
- package/table/lib/brn-header-def.directive.d.ts +9 -0
- package/table/lib/brn-paginator.directive.d.ts +41 -0
- package/table/lib/brn-table.component.d.ts +37 -0
- package/tabs/README.md +3 -0
- package/tabs/index.d.ts +14 -0
- package/tabs/lib/brn-tabs-list.directive.d.ts +17 -0
- package/tabs/lib/brn-tabs-paginated-list.directive.d.ts +196 -0
- package/tabs/lib/brn-tabs-trigger.directive.d.ts +61 -0
- package/toggle/README.md +3 -0
- package/toggle/index.d.ts +15 -0
- package/toggle/lib/brn-toggle-group.component.d.ts +68 -0
- package/toggle/lib/brn-toggle-group.token.d.ts +4 -0
- package/toggle/lib/brn-toggle.directive.d.ts +25 -0
- package/tooltip/README.md +3 -0
- package/tooltip/index.d.ts +19 -0
- package/tooltip/lib/brn-tooltip-content.component.d.ts +73 -0
- package/tooltip/lib/brn-tooltip-content.directive.d.ts +8 -0
- package/tooltip/lib/brn-tooltip-trigger.directive.d.ts +177 -0
- package/tooltip/lib/brn-tooltip.directive.d.ts +7 -0
|
@@ -0,0 +1,689 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* We are building on shoulders of giants here and adapt the implementation provided by the incredible Angular
|
|
3
|
+
* team: https://github.com/angular/components/blob/main/src/material/tooltip/tooltip.ts
|
|
4
|
+
* Check them out! Give them a try! Leave a star! Their work is incredible!
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* @license
|
|
8
|
+
* Copyright Google LLC All Rights Reserved.
|
|
9
|
+
*
|
|
10
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
11
|
+
* found in the LICENSE file at https://angular.io/license
|
|
12
|
+
*/
|
|
13
|
+
import { AriaDescriber, FocusMonitor } from '@angular/cdk/a11y';
|
|
14
|
+
import { Directionality } from '@angular/cdk/bidi';
|
|
15
|
+
import { hasModifierKey } from '@angular/cdk/keycodes';
|
|
16
|
+
import { Overlay, ScrollDispatcher, } from '@angular/cdk/overlay';
|
|
17
|
+
import { Platform, normalizePassiveListenerOptions } from '@angular/cdk/platform';
|
|
18
|
+
import { ComponentPortal } from '@angular/cdk/portal';
|
|
19
|
+
import { DOCUMENT } from '@angular/common';
|
|
20
|
+
import { Directive, ElementRef, InjectionToken, Input, NgZone, ViewContainerRef, booleanAttribute, effect, inject, isDevMode, numberAttribute, signal, } from '@angular/core';
|
|
21
|
+
import { brnDevMode } from '@spartan-ng/ui-core';
|
|
22
|
+
import { Subject } from 'rxjs';
|
|
23
|
+
import { take, takeUntil } from 'rxjs/operators';
|
|
24
|
+
import { BrnTooltipContentComponent } from './brn-tooltip-content.component';
|
|
25
|
+
import { BrnTooltipDirective } from './brn-tooltip.directive';
|
|
26
|
+
import * as i0 from "@angular/core";
|
|
27
|
+
/** Time in ms to throttle repositioning after scroll events. */
|
|
28
|
+
export const SCROLL_THROTTLE_MS = 20;
|
|
29
|
+
export function getBrnTooltipInvalidPositionError(position) {
|
|
30
|
+
return Error(`Tooltip position "${position}" is invalid.`);
|
|
31
|
+
}
|
|
32
|
+
/** Injection token that determines the scroll handling while a tooltip is visible. */
|
|
33
|
+
export const BRN_TOOLTIP_SCROLL_STRATEGY = new InjectionToken('brn-tooltip-scroll-strategy');
|
|
34
|
+
export const BRN_TOOLTIP_SCROLL_STRATEGY_FACTORY_PROVIDER = {
|
|
35
|
+
provide: BRN_TOOLTIP_SCROLL_STRATEGY,
|
|
36
|
+
deps: [Overlay],
|
|
37
|
+
useFactory: (overlay) => () => overlay.scrollStrategies.reposition({ scrollThrottle: SCROLL_THROTTLE_MS }),
|
|
38
|
+
};
|
|
39
|
+
export function BRN_TOOLTIP_DEFAULT_OPTIONS_FACTORY() {
|
|
40
|
+
return {
|
|
41
|
+
showDelay: 0,
|
|
42
|
+
hideDelay: 0,
|
|
43
|
+
touchendHideDelay: 1500,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export const BRN_TOOLTIP_DEFAULT_OPTIONS = new InjectionToken('mat-tooltip-default-options', {
|
|
47
|
+
providedIn: 'root',
|
|
48
|
+
factory: BRN_TOOLTIP_DEFAULT_OPTIONS_FACTORY,
|
|
49
|
+
});
|
|
50
|
+
const PANEL_CLASS = 'tooltip-panel';
|
|
51
|
+
/** Options used to bind passive event listeners. */
|
|
52
|
+
const passiveListenerOptions = normalizePassiveListenerOptions({ passive: true });
|
|
53
|
+
/**
|
|
54
|
+
* Time between the user putting the pointer on a tooltip
|
|
55
|
+
* trigger and the long press event being fired.
|
|
56
|
+
*/
|
|
57
|
+
const LONGPRESS_DELAY = 500;
|
|
58
|
+
// These constants were taken from MDC's `numbers` object.
|
|
59
|
+
const MIN_VIEWPORT_TOOLTIP_THRESHOLD = 8;
|
|
60
|
+
const UNBOUNDED_ANCHOR_GAP = 8;
|
|
61
|
+
export class BrnTooltipTriggerDirective {
|
|
62
|
+
_tooltipDirective = inject(BrnTooltipDirective, { optional: true });
|
|
63
|
+
_tooltipComponent = BrnTooltipContentComponent;
|
|
64
|
+
_cssClassPrefix = 'brn';
|
|
65
|
+
_destroyed = new Subject();
|
|
66
|
+
_passiveListeners = [];
|
|
67
|
+
_defaultOptions = inject(BRN_TOOLTIP_DEFAULT_OPTIONS, { optional: true });
|
|
68
|
+
_overlay = inject(Overlay);
|
|
69
|
+
_elementRef = inject((ElementRef));
|
|
70
|
+
_scrollDispatcher = inject(ScrollDispatcher);
|
|
71
|
+
_viewContainerRef = inject(ViewContainerRef);
|
|
72
|
+
_ngZone = inject(NgZone);
|
|
73
|
+
_platform = inject(Platform);
|
|
74
|
+
_ariaDescriber = inject(AriaDescriber);
|
|
75
|
+
_focusMonitor = inject(FocusMonitor);
|
|
76
|
+
_dir = inject(Directionality);
|
|
77
|
+
_scrollStrategy = inject(BRN_TOOLTIP_SCROLL_STRATEGY);
|
|
78
|
+
_document = inject(DOCUMENT);
|
|
79
|
+
_portal;
|
|
80
|
+
_viewInitialized = false;
|
|
81
|
+
_pointerExitEventsInitialized = false;
|
|
82
|
+
_viewportMargin = 8;
|
|
83
|
+
_currentPosition;
|
|
84
|
+
_touchstartTimeout;
|
|
85
|
+
_overlayRef = null;
|
|
86
|
+
_tooltipInstance = null;
|
|
87
|
+
/** Allows the user to define the position of the tooltip relative to the parent element */
|
|
88
|
+
_position = signal('above');
|
|
89
|
+
get position() {
|
|
90
|
+
return this._position();
|
|
91
|
+
}
|
|
92
|
+
set position(value) {
|
|
93
|
+
if (value !== this._position()) {
|
|
94
|
+
this._position.set(value);
|
|
95
|
+
if (this._overlayRef) {
|
|
96
|
+
this._updatePosition(this._overlayRef);
|
|
97
|
+
this._tooltipInstance?.show(0);
|
|
98
|
+
this._overlayRef.updatePosition();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Whether tooltip should be relative to the click or touch origin
|
|
104
|
+
* instead of outside the element bounding box.
|
|
105
|
+
*/
|
|
106
|
+
_positionAtOrigin = signal(false);
|
|
107
|
+
get positionAtOrigin() {
|
|
108
|
+
return this._positionAtOrigin();
|
|
109
|
+
}
|
|
110
|
+
set positionAtOrigin(value) {
|
|
111
|
+
this._positionAtOrigin.set(value);
|
|
112
|
+
this._detach();
|
|
113
|
+
this._overlayRef = null;
|
|
114
|
+
}
|
|
115
|
+
/** Disables the display of the tooltip. */
|
|
116
|
+
_disabled = signal(false);
|
|
117
|
+
get disabled() {
|
|
118
|
+
return this._disabled();
|
|
119
|
+
}
|
|
120
|
+
set disabled(value) {
|
|
121
|
+
this._disabled.set(value);
|
|
122
|
+
// If tooltip is disabled, hide immediately.
|
|
123
|
+
if (value) {
|
|
124
|
+
this.hide(0);
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
this._setupPointerEnterEventsIfNeeded();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/** The default delay in ms before showing the tooltip after show is called */
|
|
131
|
+
_showDelay = signal(0);
|
|
132
|
+
get showDelay() {
|
|
133
|
+
return this._showDelay();
|
|
134
|
+
}
|
|
135
|
+
set showDelay(value) {
|
|
136
|
+
this._showDelay.set(value);
|
|
137
|
+
}
|
|
138
|
+
/** The default delay in ms before hiding the tooltip after hide is called */
|
|
139
|
+
_hideDelay = signal(0);
|
|
140
|
+
get hideDelay() {
|
|
141
|
+
return this._hideDelay();
|
|
142
|
+
}
|
|
143
|
+
set hideDelay(value) {
|
|
144
|
+
this._hideDelay.set(value);
|
|
145
|
+
if (this._tooltipInstance) {
|
|
146
|
+
this._tooltipInstance._mouseLeaveHideDelay = this._hideDelay();
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/** The default duration in ms that exit animation takes before hiding */
|
|
150
|
+
_exitAnimationDuration = signal(0);
|
|
151
|
+
get exitAnimationDuration() {
|
|
152
|
+
return this._exitAnimationDuration();
|
|
153
|
+
}
|
|
154
|
+
set exitAnimationDuration(value) {
|
|
155
|
+
this._exitAnimationDuration.set(value);
|
|
156
|
+
if (this._tooltipInstance) {
|
|
157
|
+
this._tooltipInstance._exitAnimationDuration = this._exitAnimationDuration();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/** The default delay in ms before hiding the tooltip after hide is called */
|
|
161
|
+
_tooltipContentClasses = signal('');
|
|
162
|
+
get tooltipContentClasses() {
|
|
163
|
+
return this._tooltipContentClasses();
|
|
164
|
+
}
|
|
165
|
+
set tooltipContentClasses(value) {
|
|
166
|
+
this._tooltipContentClasses.set(value ?? '');
|
|
167
|
+
if (this._tooltipInstance) {
|
|
168
|
+
this._tooltipInstance._tooltipClasses.set(value ?? '');
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* How touch gestures should be handled by the tooltip. On touch devices the tooltip directive
|
|
173
|
+
* uses a long press gesture to show and hide, however it can conflict with the native browser
|
|
174
|
+
* gestures. To work around the conflict, Angular Material disables native gestures on the
|
|
175
|
+
* trigger, but that might not be desirable on particular elements (e.g. inputs and draggable
|
|
176
|
+
* elements). The different values for this option configure the touch event handling as follows:
|
|
177
|
+
* - `auto` - Enables touch gestures for all elements, but tries to avoid conflicts with native
|
|
178
|
+
* browser gestures on particular elements. In particular, it allows text selection on inputs
|
|
179
|
+
* and textareas, and preserves the native browser dragging on elements marked as `draggable`.
|
|
180
|
+
* - `on` - Enables touch gestures for all elements and disables native
|
|
181
|
+
* browser gestures with no exceptions.
|
|
182
|
+
* - `off` - Disables touch gestures. Note that this will prevent the tooltip from
|
|
183
|
+
* showing on touch devices.
|
|
184
|
+
*/
|
|
185
|
+
_touchGestures = signal('auto');
|
|
186
|
+
set touchGestures(value) {
|
|
187
|
+
this._touchGestures.set(value);
|
|
188
|
+
}
|
|
189
|
+
get touchGestures() {
|
|
190
|
+
return this._touchGestures();
|
|
191
|
+
}
|
|
192
|
+
/** The message to be used to describe the aria in the tooltip */
|
|
193
|
+
_ariaDescribedBy = '';
|
|
194
|
+
get ariaDescribedBy() {
|
|
195
|
+
return this._ariaDescribedBy;
|
|
196
|
+
}
|
|
197
|
+
set ariaDescribedBy(value) {
|
|
198
|
+
this._ariaDescriber.removeDescription(this._elementRef.nativeElement, this._ariaDescribedBy, 'tooltip');
|
|
199
|
+
// If the message is not a string (e.g. number), convert it to a string and trim it.
|
|
200
|
+
// Must convert with `String(value)`, not `${value}`, otherwise Closure Compiler optimises
|
|
201
|
+
// away the string-conversion: https://github.com/angular/components/issues/20684
|
|
202
|
+
this._ariaDescribedBy = value !== null ? String(value).trim() : '';
|
|
203
|
+
if (this._ariaDescribedBy && !this._isTooltipVisible()) {
|
|
204
|
+
this._ngZone.runOutsideAngular(() => {
|
|
205
|
+
// The `AriaDescriber` has some functionality that avoids adding a description if it's the
|
|
206
|
+
// same as the `aria-label` of an element, however we can't know whether the tooltip trigger
|
|
207
|
+
// has a data-bound `aria-label` or when it'll be set for the first time. We can avoid the
|
|
208
|
+
// issue by deferring the description by a tick so Angular has time to set the `aria-label`.
|
|
209
|
+
Promise.resolve().then(() => {
|
|
210
|
+
this._ariaDescriber.describe(this._elementRef.nativeElement, this._ariaDescribedBy, 'tooltip');
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/** The content to be displayed in the tooltip */
|
|
216
|
+
_content = null;
|
|
217
|
+
get content() {
|
|
218
|
+
return this._content;
|
|
219
|
+
}
|
|
220
|
+
set content(value) {
|
|
221
|
+
this._content = value;
|
|
222
|
+
if (!this._content && this._isTooltipVisible()) {
|
|
223
|
+
this.hide(0);
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
this._setupPointerEnterEventsIfNeeded();
|
|
227
|
+
this._updateTooltipContent();
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
constructor() {
|
|
231
|
+
if (this._defaultOptions) {
|
|
232
|
+
this._showDelay.set(this._defaultOptions.showDelay);
|
|
233
|
+
this._hideDelay.set(this._defaultOptions.hideDelay);
|
|
234
|
+
if (this._defaultOptions.position) {
|
|
235
|
+
this.position = this._defaultOptions.position;
|
|
236
|
+
}
|
|
237
|
+
if (this._defaultOptions.positionAtOrigin) {
|
|
238
|
+
this.positionAtOrigin = this._defaultOptions.positionAtOrigin;
|
|
239
|
+
}
|
|
240
|
+
if (this._defaultOptions.touchGestures) {
|
|
241
|
+
this.touchGestures = this._defaultOptions.touchGestures;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
this._dir.change.pipe(takeUntil(this._destroyed)).subscribe(() => {
|
|
245
|
+
if (this._overlayRef) {
|
|
246
|
+
this._updatePosition(this._overlayRef);
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
this._viewportMargin = MIN_VIEWPORT_TOOLTIP_THRESHOLD;
|
|
250
|
+
if (this._tooltipDirective) {
|
|
251
|
+
effect(() => {
|
|
252
|
+
if (this._tooltipDirective) {
|
|
253
|
+
this.content = this._tooltipDirective.tooltipTemplate();
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
ngAfterViewInit() {
|
|
259
|
+
// This needs to happen after view init so the initial values for all inputs have been set.
|
|
260
|
+
this._viewInitialized = true;
|
|
261
|
+
this._setupPointerEnterEventsIfNeeded();
|
|
262
|
+
this._focusMonitor
|
|
263
|
+
.monitor(this._elementRef)
|
|
264
|
+
.pipe(takeUntil(this._destroyed))
|
|
265
|
+
.subscribe((origin) => {
|
|
266
|
+
// Note that the focus monitor runs outside the Angular zone.
|
|
267
|
+
if (!origin) {
|
|
268
|
+
this._ngZone.run(() => this.hide(0));
|
|
269
|
+
}
|
|
270
|
+
else if (origin === 'keyboard') {
|
|
271
|
+
this._ngZone.run(() => this.show());
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
if (brnDevMode && !this._ariaDescribedBy) {
|
|
275
|
+
console.warn('BrnTooltip: "aria-describedby" attribute is required for accessibility');
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Dispose the tooltip when destroyed.
|
|
280
|
+
*/
|
|
281
|
+
ngOnDestroy() {
|
|
282
|
+
const nativeElement = this._elementRef.nativeElement;
|
|
283
|
+
clearTimeout(this._touchstartTimeout);
|
|
284
|
+
if (this._overlayRef) {
|
|
285
|
+
this._overlayRef.dispose();
|
|
286
|
+
this._tooltipInstance = null;
|
|
287
|
+
}
|
|
288
|
+
// Clean up the event listeners set in the constructor
|
|
289
|
+
this._passiveListeners.forEach(([event, listener]) => nativeElement.removeEventListener(event, listener, passiveListenerOptions));
|
|
290
|
+
this._passiveListeners.length = 0;
|
|
291
|
+
this._destroyed.next();
|
|
292
|
+
this._destroyed.complete();
|
|
293
|
+
this._ariaDescriber.removeDescription(nativeElement, this._ariaDescribedBy, 'tooltip');
|
|
294
|
+
this._focusMonitor.stopMonitoring(nativeElement);
|
|
295
|
+
}
|
|
296
|
+
/** Shows the tooltip after the delay in ms, defaults to tooltip-delay-show or 0ms if no input */
|
|
297
|
+
show(delay = this.showDelay, origin) {
|
|
298
|
+
if (this.disabled || this._isTooltipVisible()) {
|
|
299
|
+
this._tooltipInstance?._cancelPendingAnimations();
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
const overlayRef = this._createOverlay(origin);
|
|
303
|
+
this._detach();
|
|
304
|
+
this._portal = this._portal || new ComponentPortal(this._tooltipComponent, this._viewContainerRef);
|
|
305
|
+
const instance = (this._tooltipInstance = overlayRef.attach(this._portal).instance);
|
|
306
|
+
instance._triggerElement = this._elementRef.nativeElement;
|
|
307
|
+
instance._mouseLeaveHideDelay = this._hideDelay();
|
|
308
|
+
instance._tooltipClasses.set(this._tooltipContentClasses());
|
|
309
|
+
instance._exitAnimationDuration = this._exitAnimationDuration();
|
|
310
|
+
instance.side.set(this._currentPosition ?? 'above');
|
|
311
|
+
instance.afterHidden.pipe(takeUntil(this._destroyed)).subscribe(() => this._detach());
|
|
312
|
+
this._updateTooltipContent();
|
|
313
|
+
instance.show(delay);
|
|
314
|
+
}
|
|
315
|
+
/** Hides the tooltip after the delay in ms, defaults to tooltip-delay-hide or 0ms if no input */
|
|
316
|
+
hide(delay = this.hideDelay, exitAnimationDuration = this.exitAnimationDuration) {
|
|
317
|
+
const instance = this._tooltipInstance;
|
|
318
|
+
if (instance) {
|
|
319
|
+
if (instance.isVisible()) {
|
|
320
|
+
instance.hide(delay, exitAnimationDuration);
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
instance._cancelPendingAnimations();
|
|
324
|
+
this._detach();
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
toggle(origin) {
|
|
329
|
+
this._isTooltipVisible() ? this.hide() : this.show(undefined, origin);
|
|
330
|
+
}
|
|
331
|
+
_isTooltipVisible() {
|
|
332
|
+
return !!this._tooltipInstance && this._tooltipInstance.isVisible();
|
|
333
|
+
}
|
|
334
|
+
_createOverlay(origin) {
|
|
335
|
+
if (this._overlayRef) {
|
|
336
|
+
const existingStrategy = this._overlayRef.getConfig().positionStrategy;
|
|
337
|
+
if ((!this.positionAtOrigin || !origin) && existingStrategy._origin instanceof ElementRef) {
|
|
338
|
+
return this._overlayRef;
|
|
339
|
+
}
|
|
340
|
+
this._detach();
|
|
341
|
+
}
|
|
342
|
+
const scrollableAncestors = this._scrollDispatcher.getAncestorScrollContainers(this._elementRef);
|
|
343
|
+
// Create connected position strategy that listens for scroll events to reposition.
|
|
344
|
+
const strategy = this._overlay
|
|
345
|
+
.position()
|
|
346
|
+
.flexibleConnectedTo(this.positionAtOrigin ? origin || this._elementRef : this._elementRef)
|
|
347
|
+
.withTransformOriginOn(`.${this._cssClassPrefix}-tooltip`)
|
|
348
|
+
.withFlexibleDimensions(false)
|
|
349
|
+
.withViewportMargin(this._viewportMargin)
|
|
350
|
+
.withScrollableContainers(scrollableAncestors);
|
|
351
|
+
strategy.positionChanges.pipe(takeUntil(this._destroyed)).subscribe((change) => {
|
|
352
|
+
this._updateCurrentPositionClass(change.connectionPair);
|
|
353
|
+
if (this._tooltipInstance) {
|
|
354
|
+
if (change.scrollableViewProperties.isOverlayClipped && this._tooltipInstance.isVisible()) {
|
|
355
|
+
// After position changes occur and the overlay is clipped by
|
|
356
|
+
// a parent scrollable then close the tooltip.
|
|
357
|
+
this._ngZone.run(() => this.hide(0));
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
this._overlayRef = this._overlay.create({
|
|
362
|
+
direction: this._dir,
|
|
363
|
+
positionStrategy: strategy,
|
|
364
|
+
panelClass: `${this._cssClassPrefix}-${PANEL_CLASS}`,
|
|
365
|
+
scrollStrategy: this._scrollStrategy(),
|
|
366
|
+
});
|
|
367
|
+
this._updatePosition(this._overlayRef);
|
|
368
|
+
this._overlayRef
|
|
369
|
+
.detachments()
|
|
370
|
+
.pipe(takeUntil(this._destroyed))
|
|
371
|
+
.subscribe(() => this._detach());
|
|
372
|
+
this._overlayRef
|
|
373
|
+
.outsidePointerEvents()
|
|
374
|
+
.pipe(takeUntil(this._destroyed))
|
|
375
|
+
.subscribe(() => this._tooltipInstance?._handleBodyInteraction());
|
|
376
|
+
this._overlayRef
|
|
377
|
+
.keydownEvents()
|
|
378
|
+
.pipe(takeUntil(this._destroyed))
|
|
379
|
+
.subscribe((event) => {
|
|
380
|
+
if (this._isTooltipVisible() && event.key === 'Escape' && !hasModifierKey(event)) {
|
|
381
|
+
event.preventDefault();
|
|
382
|
+
event.stopPropagation();
|
|
383
|
+
this._ngZone.run(() => this.hide(0));
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
if (this._defaultOptions?.disableTooltipInteractivity) {
|
|
387
|
+
this._overlayRef.addPanelClass(`${this._cssClassPrefix}-tooltip-panel-non-interactive`);
|
|
388
|
+
}
|
|
389
|
+
return this._overlayRef;
|
|
390
|
+
}
|
|
391
|
+
_detach() {
|
|
392
|
+
if (this._overlayRef?.hasAttached()) {
|
|
393
|
+
this._overlayRef.detach();
|
|
394
|
+
}
|
|
395
|
+
this._tooltipInstance = null;
|
|
396
|
+
}
|
|
397
|
+
_updatePosition(overlayRef) {
|
|
398
|
+
const position = overlayRef.getConfig().positionStrategy;
|
|
399
|
+
const origin = this._getOrigin();
|
|
400
|
+
const overlay = this._getOverlayPosition();
|
|
401
|
+
position.withPositions([
|
|
402
|
+
this._addOffset({ ...origin.main, ...overlay.main }),
|
|
403
|
+
this._addOffset({ ...origin.fallback, ...overlay.fallback }),
|
|
404
|
+
]);
|
|
405
|
+
}
|
|
406
|
+
/** Adds the configured offset to a position. Used as a hook for child classes. */
|
|
407
|
+
_addOffset(position) {
|
|
408
|
+
const offset = UNBOUNDED_ANCHOR_GAP;
|
|
409
|
+
const isLtr = !this._dir || this._dir.value === 'ltr';
|
|
410
|
+
if (position.originY === 'top') {
|
|
411
|
+
position.offsetY = -offset;
|
|
412
|
+
}
|
|
413
|
+
else if (position.originY === 'bottom') {
|
|
414
|
+
position.offsetY = offset;
|
|
415
|
+
}
|
|
416
|
+
else if (position.originX === 'start') {
|
|
417
|
+
position.offsetX = isLtr ? -offset : offset;
|
|
418
|
+
}
|
|
419
|
+
else if (position.originX === 'end') {
|
|
420
|
+
position.offsetX = isLtr ? offset : -offset;
|
|
421
|
+
}
|
|
422
|
+
return position;
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Returns the origin position and a fallback position based on the user's position preference.
|
|
426
|
+
* The fallback position is the inverse of the origin (e.g. `'below' -> 'above'`).
|
|
427
|
+
*/
|
|
428
|
+
_getOrigin() {
|
|
429
|
+
const isLtr = !this._dir || this._dir.value === 'ltr';
|
|
430
|
+
const position = this.position;
|
|
431
|
+
let originPosition;
|
|
432
|
+
if (position === 'above' || position === 'below') {
|
|
433
|
+
originPosition = { originX: 'center', originY: position === 'above' ? 'top' : 'bottom' };
|
|
434
|
+
}
|
|
435
|
+
else if (position === 'before' || (position === 'left' && isLtr) || (position === 'right' && !isLtr)) {
|
|
436
|
+
originPosition = { originX: 'start', originY: 'center' };
|
|
437
|
+
}
|
|
438
|
+
else if (position === 'after' || (position === 'right' && isLtr) || (position === 'left' && !isLtr)) {
|
|
439
|
+
originPosition = { originX: 'end', originY: 'center' };
|
|
440
|
+
}
|
|
441
|
+
else if (typeof isDevMode() === 'undefined' || isDevMode()) {
|
|
442
|
+
throw getBrnTooltipInvalidPositionError(position);
|
|
443
|
+
}
|
|
444
|
+
const { x, y } = this._invertPosition(originPosition.originX, originPosition.originY);
|
|
445
|
+
return {
|
|
446
|
+
main: originPosition,
|
|
447
|
+
fallback: { originX: x, originY: y },
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
/** Returns the overlay position and a fallback position based on the user's preference */
|
|
451
|
+
_getOverlayPosition() {
|
|
452
|
+
const isLtr = !this._dir || this._dir.value === 'ltr';
|
|
453
|
+
const position = this.position;
|
|
454
|
+
let overlayPosition;
|
|
455
|
+
if (position === 'above') {
|
|
456
|
+
overlayPosition = { overlayX: 'center', overlayY: 'bottom' };
|
|
457
|
+
}
|
|
458
|
+
else if (position === 'below') {
|
|
459
|
+
overlayPosition = { overlayX: 'center', overlayY: 'top' };
|
|
460
|
+
}
|
|
461
|
+
else if (position === 'before' || (position === 'left' && isLtr) || (position === 'right' && !isLtr)) {
|
|
462
|
+
overlayPosition = { overlayX: 'end', overlayY: 'center' };
|
|
463
|
+
}
|
|
464
|
+
else if (position === 'after' || (position === 'right' && isLtr) || (position === 'left' && !isLtr)) {
|
|
465
|
+
overlayPosition = { overlayX: 'start', overlayY: 'center' };
|
|
466
|
+
}
|
|
467
|
+
else if (typeof isDevMode() === 'undefined' || isDevMode()) {
|
|
468
|
+
throw getBrnTooltipInvalidPositionError(position);
|
|
469
|
+
}
|
|
470
|
+
const { x, y } = this._invertPosition(overlayPosition.overlayX, overlayPosition.overlayY);
|
|
471
|
+
return {
|
|
472
|
+
main: overlayPosition,
|
|
473
|
+
fallback: { overlayX: x, overlayY: y },
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
/** Updates the tooltip message and repositions the overlay according to the new message length */
|
|
477
|
+
_updateTooltipContent() {
|
|
478
|
+
// Must wait for the template to be painted to the tooltip so that the overlay can properly
|
|
479
|
+
// calculate the correct positioning based on the size of the tek-pate.
|
|
480
|
+
if (this._tooltipInstance) {
|
|
481
|
+
this._tooltipInstance.content = this.content;
|
|
482
|
+
this._tooltipInstance._markForCheck();
|
|
483
|
+
this._ngZone.onMicrotaskEmpty.pipe(take(1), takeUntil(this._destroyed)).subscribe(() => {
|
|
484
|
+
if (this._tooltipInstance) {
|
|
485
|
+
this._overlayRef?.updatePosition();
|
|
486
|
+
}
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
/** Inverts an overlay position. */
|
|
491
|
+
_invertPosition(x, y) {
|
|
492
|
+
if (this.position === 'above' || this.position === 'below') {
|
|
493
|
+
if (y === 'top') {
|
|
494
|
+
y = 'bottom';
|
|
495
|
+
}
|
|
496
|
+
else if (y === 'bottom') {
|
|
497
|
+
y = 'top';
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
else {
|
|
501
|
+
if (x === 'end') {
|
|
502
|
+
x = 'start';
|
|
503
|
+
}
|
|
504
|
+
else if (x === 'start') {
|
|
505
|
+
x = 'end';
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
return { x, y };
|
|
509
|
+
}
|
|
510
|
+
/** Updates the class on the overlay panel based on the current position of the tooltip. */
|
|
511
|
+
_updateCurrentPositionClass(connectionPair) {
|
|
512
|
+
const { overlayY, originX, originY } = connectionPair;
|
|
513
|
+
let newPosition;
|
|
514
|
+
// If the overlay is in the middle along the Y axis,
|
|
515
|
+
// it means that it's either before or after.
|
|
516
|
+
if (overlayY === 'center') {
|
|
517
|
+
// Note that since this information is used for styling, we want to
|
|
518
|
+
// resolve `start` and `end` to their real values, otherwise consumers
|
|
519
|
+
// would have to remember to do it themselves on each consumption.
|
|
520
|
+
if (this._dir && this._dir.value === 'rtl') {
|
|
521
|
+
newPosition = originX === 'end' ? 'left' : 'right';
|
|
522
|
+
}
|
|
523
|
+
else {
|
|
524
|
+
newPosition = originX === 'start' ? 'left' : 'right';
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
else {
|
|
528
|
+
newPosition = overlayY === 'bottom' && originY === 'top' ? 'above' : 'below';
|
|
529
|
+
}
|
|
530
|
+
if (newPosition !== this._currentPosition) {
|
|
531
|
+
this._tooltipInstance?.side.set(newPosition);
|
|
532
|
+
this._currentPosition = newPosition;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
/** Binds the pointer events to the tooltip trigger. */
|
|
536
|
+
_setupPointerEnterEventsIfNeeded() {
|
|
537
|
+
// Optimization: Defer hooking up events if there's no content or the tooltip is disabled.
|
|
538
|
+
if (this._disabled() || !this.content || !this._viewInitialized || this._passiveListeners.length) {
|
|
539
|
+
return;
|
|
540
|
+
}
|
|
541
|
+
// The mouse events shouldn't be bound on mobile devices, because they can prevent the
|
|
542
|
+
// first tap from firing its click event or can cause the tooltip to open for clicks.
|
|
543
|
+
if (this._platformSupportsMouseEvents()) {
|
|
544
|
+
this._passiveListeners.push([
|
|
545
|
+
'mouseenter',
|
|
546
|
+
(event) => {
|
|
547
|
+
this._setupPointerExitEventsIfNeeded();
|
|
548
|
+
let point = undefined;
|
|
549
|
+
if (event.x !== undefined && event.y !== undefined) {
|
|
550
|
+
point = event;
|
|
551
|
+
}
|
|
552
|
+
this.show(undefined, point);
|
|
553
|
+
},
|
|
554
|
+
]);
|
|
555
|
+
}
|
|
556
|
+
else if (this.touchGestures !== 'off') {
|
|
557
|
+
this._disableNativeGesturesIfNecessary();
|
|
558
|
+
this._passiveListeners.push([
|
|
559
|
+
'touchstart',
|
|
560
|
+
(event) => {
|
|
561
|
+
const touch = event.targetTouches?.[0];
|
|
562
|
+
const origin = touch ? { x: touch.clientX, y: touch.clientY } : undefined;
|
|
563
|
+
// Note that it's important that we don't `preventDefault` here,
|
|
564
|
+
// because it can prevent click events from firing on the element.
|
|
565
|
+
this._setupPointerExitEventsIfNeeded();
|
|
566
|
+
clearTimeout(this._touchstartTimeout);
|
|
567
|
+
this._touchstartTimeout = setTimeout(() => this.show(undefined, origin), LONGPRESS_DELAY);
|
|
568
|
+
},
|
|
569
|
+
]);
|
|
570
|
+
}
|
|
571
|
+
this._addListeners(this._passiveListeners);
|
|
572
|
+
}
|
|
573
|
+
_setupPointerExitEventsIfNeeded() {
|
|
574
|
+
if (this._pointerExitEventsInitialized) {
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
this._pointerExitEventsInitialized = true;
|
|
578
|
+
const exitListeners = [];
|
|
579
|
+
if (this._platformSupportsMouseEvents()) {
|
|
580
|
+
exitListeners.push([
|
|
581
|
+
'mouseleave',
|
|
582
|
+
(event) => {
|
|
583
|
+
const newTarget = event.relatedTarget;
|
|
584
|
+
if (!newTarget || !this._overlayRef?.overlayElement.contains(newTarget)) {
|
|
585
|
+
this.hide();
|
|
586
|
+
}
|
|
587
|
+
},
|
|
588
|
+
], ['wheel', (event) => this._wheelListener(event)]);
|
|
589
|
+
}
|
|
590
|
+
else if (this.touchGestures !== 'off') {
|
|
591
|
+
this._disableNativeGesturesIfNecessary();
|
|
592
|
+
const touchendListener = () => {
|
|
593
|
+
clearTimeout(this._touchstartTimeout);
|
|
594
|
+
this.hide(this._defaultOptions?.touchendHideDelay);
|
|
595
|
+
};
|
|
596
|
+
exitListeners.push(['touchend', touchendListener], ['touchcancel', touchendListener]);
|
|
597
|
+
}
|
|
598
|
+
this._addListeners(exitListeners);
|
|
599
|
+
this._passiveListeners.push(...exitListeners);
|
|
600
|
+
}
|
|
601
|
+
_addListeners(listeners) {
|
|
602
|
+
listeners.forEach(([event, listener]) => {
|
|
603
|
+
this._elementRef.nativeElement.addEventListener(event, listener, passiveListenerOptions);
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
_platformSupportsMouseEvents() {
|
|
607
|
+
return !this._platform.IOS && !this._platform.ANDROID;
|
|
608
|
+
}
|
|
609
|
+
/** Listener for the `wheel` event on the element. */
|
|
610
|
+
_wheelListener(event) {
|
|
611
|
+
if (this._isTooltipVisible()) {
|
|
612
|
+
const elementUnderPointer = this._document.elementFromPoint(event.clientX, event.clientY);
|
|
613
|
+
const element = this._elementRef.nativeElement;
|
|
614
|
+
// On non-touch devices we depend on the `mouseleave` event to close the tooltip, but it
|
|
615
|
+
// won't fire if the user scrolls away using the wheel without moving their cursor. We
|
|
616
|
+
// work around it by finding the element under the user's cursor and closing the tooltip
|
|
617
|
+
// if it's not the trigger.
|
|
618
|
+
if (elementUnderPointer !== element && !element.contains(elementUnderPointer)) {
|
|
619
|
+
this.hide();
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
/** Disables the native browser gestures, based on how the tooltip has been configured. */
|
|
624
|
+
_disableNativeGesturesIfNecessary() {
|
|
625
|
+
const gestures = this.touchGestures;
|
|
626
|
+
if (gestures !== 'off') {
|
|
627
|
+
const element = this._elementRef.nativeElement;
|
|
628
|
+
const style = element.style;
|
|
629
|
+
// If gestures are set to `auto`, we don't disable text selection on inputs and
|
|
630
|
+
// textareas, because it prevents the user from typing into them on iOS Safari.
|
|
631
|
+
if (gestures === 'on' || (element.nodeName !== 'INPUT' && element.nodeName !== 'TEXTAREA')) {
|
|
632
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
633
|
+
style.userSelect = style.msUserSelect = style.webkitUserSelect = style.MozUserSelect = 'none';
|
|
634
|
+
}
|
|
635
|
+
// If we have `auto` gestures and the element uses native HTML dragging,
|
|
636
|
+
// we don't set `-webkit-user-drag` because it prevents the native behavior.
|
|
637
|
+
if (gestures === 'on' || !element.draggable) {
|
|
638
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
639
|
+
style.webkitUserDrag = 'none';
|
|
640
|
+
}
|
|
641
|
+
style.touchAction = 'none';
|
|
642
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
643
|
+
style.webkitTapHighlightColor = 'transparent';
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.5", ngImport: i0, type: BrnTooltipTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
647
|
+
/** @nocollapse */ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "18.2.5", type: BrnTooltipTriggerDirective, isStandalone: true, selector: "[brnTooltipTrigger]", inputs: { position: "position", positionAtOrigin: ["positionAtOrigin", "positionAtOrigin", booleanAttribute], disabled: ["brnTooltipDisabled", "disabled", booleanAttribute], showDelay: ["showDelay", "showDelay", numberAttribute], hideDelay: ["hideDelay", "hideDelay", numberAttribute], exitAnimationDuration: ["exitAnimationDuration", "exitAnimationDuration", numberAttribute], tooltipContentClasses: "tooltipContentClasses", touchGestures: "touchGestures", ariaDescribedBy: ["aria-describedby", "ariaDescribedBy"], content: ["brnTooltipTrigger", "content"] }, host: { properties: { "class.brn-tooltip-disabled": "disabled" }, classAttribute: "brn-tooltip-trigger" }, providers: [BRN_TOOLTIP_SCROLL_STRATEGY_FACTORY_PROVIDER], exportAs: ["brnTooltipTrigger"], ngImport: i0 });
|
|
648
|
+
}
|
|
649
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.5", ngImport: i0, type: BrnTooltipTriggerDirective, decorators: [{
|
|
650
|
+
type: Directive,
|
|
651
|
+
args: [{
|
|
652
|
+
selector: '[brnTooltipTrigger]',
|
|
653
|
+
standalone: true,
|
|
654
|
+
exportAs: 'brnTooltipTrigger',
|
|
655
|
+
providers: [BRN_TOOLTIP_SCROLL_STRATEGY_FACTORY_PROVIDER],
|
|
656
|
+
host: {
|
|
657
|
+
class: 'brn-tooltip-trigger',
|
|
658
|
+
'[class.brn-tooltip-disabled]': 'disabled',
|
|
659
|
+
},
|
|
660
|
+
}]
|
|
661
|
+
}], ctorParameters: () => [], propDecorators: { position: [{
|
|
662
|
+
type: Input
|
|
663
|
+
}], positionAtOrigin: [{
|
|
664
|
+
type: Input,
|
|
665
|
+
args: [{ transform: booleanAttribute }]
|
|
666
|
+
}], disabled: [{
|
|
667
|
+
type: Input,
|
|
668
|
+
args: [{ transform: booleanAttribute, alias: 'brnTooltipDisabled' }]
|
|
669
|
+
}], showDelay: [{
|
|
670
|
+
type: Input,
|
|
671
|
+
args: [{ transform: numberAttribute }]
|
|
672
|
+
}], hideDelay: [{
|
|
673
|
+
type: Input,
|
|
674
|
+
args: [{ transform: numberAttribute }]
|
|
675
|
+
}], exitAnimationDuration: [{
|
|
676
|
+
type: Input,
|
|
677
|
+
args: [{ transform: numberAttribute }]
|
|
678
|
+
}], tooltipContentClasses: [{
|
|
679
|
+
type: Input
|
|
680
|
+
}], touchGestures: [{
|
|
681
|
+
type: Input
|
|
682
|
+
}], ariaDescribedBy: [{
|
|
683
|
+
type: Input,
|
|
684
|
+
args: ['aria-describedby']
|
|
685
|
+
}], content: [{
|
|
686
|
+
type: Input,
|
|
687
|
+
args: ['brnTooltipTrigger']
|
|
688
|
+
}] } });
|
|
689
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJuLXRvb2x0aXAtdHJpZ2dlci5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzL2JyYWluL3Rvb2x0aXAvc3JjL2xpYi9icm4tdG9vbHRpcC10cmlnZ2VyLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBRUg7Ozs7OztHQU1HO0FBQ0gsT0FBTyxFQUFFLGFBQWEsRUFBRSxZQUFZLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDbkQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3ZELE9BQU8sRUFNTixPQUFPLEVBR1AsZ0JBQWdCLEdBR2hCLE1BQU0sc0JBQXNCLENBQUM7QUFDOUIsT0FBTyxFQUFFLFFBQVEsRUFBRSwrQkFBK0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ2xGLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN0RCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUVOLFNBQVMsRUFDVCxVQUFVLEVBQ1YsY0FBYyxFQUNkLEtBQUssRUFDTCxNQUFNLEVBR04sZ0JBQWdCLEVBQ2hCLGdCQUFnQixFQUNoQixNQUFNLEVBQ04sTUFBTSxFQUNOLFNBQVMsRUFDVCxlQUFlLEVBQ2YsTUFBTSxHQUNOLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDakQsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDN0UsT0FBTyxF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QixnQkFBZ0IsZ0RBYWhCLGdCQUFnQix5Q0FrQmhCLGVBQWUseUNBV2YsZUFBZSw2RUFlZixlQUFlLGdUQXBIeEIsQ0FBQyw0Q0FBNEMsQ0FBQzs7MkZBTTdDLDBCQUEwQjtrQkFWdEMsU0FBUzttQkFBQztvQkFDVixRQUFRLEVBQUUscUJBQXFCO29CQUMvQixVQUFVLEVBQUUsSUFBSTtvQkFDaEIsUUFBUSxFQUFFLG1CQUFtQjtvQkFDN0IsU0FBUyxFQUFFLENBQUMsNENBQTRDLENBQUM7b0JBQ3pELElBQUksRUFBRTt3QkFDTCxLQUFLLEVBQUUscUJBQXFCO3dCQUM1Qiw4QkFBOEIsRUFBRSxVQUFVO3FCQUMxQztpQkFDRDt3REFpQ1csUUFBUTtzQkFEbEIsS0FBSztnQkF1QkssZ0JBQWdCO3NCQUQxQixLQUFLO3VCQUFDLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixFQUFFO2dCQWMzQixRQUFRO3NCQURsQixLQUFLO3VCQUFDLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixFQUFFLEtBQUssRUFBRSxvQkFBb0IsRUFBRTtnQkFtQnhELFNBQVM7c0JBRG5CLEtBQUs7dUJBQUMsRUFBRSxTQUFTLEVBQUUsZUFBZSxFQUFFO2dCQVkxQixTQUFTO3NCQURuQixLQUFLO3VCQUFDLEVBQUUsU0FBUyxFQUFFLGVBQWUsRUFBRTtnQkFnQjFCLHFCQUFxQjtzQkFEL0IsS0FBSzt1QkFBQyxFQUFFLFNBQVMsRUFBRSxlQUFlLEVBQUU7Z0JBZ0IxQixxQkFBcUI7c0JBRC9CLEtBQUs7Z0JBNkJLLGFBQWE7c0JBRHZCLEtBQUs7Z0JBWUssZUFBZTtzQkFEekIsS0FBSzt1QkFBQyxrQkFBa0I7Z0JBNkJkLE9BQU87c0JBRGpCLEtBQUs7dUJBQUMsbUJBQW1CIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBXZSBhcmUgYnVpbGRpbmcgb24gc2hvdWxkZXJzIG9mIGdpYW50cyBoZXJlIGFuZCBhZGFwdCB0aGUgaW1wbGVtZW50YXRpb24gcHJvdmlkZWQgYnkgdGhlIGluY3JlZGlibGUgQW5ndWxhclxuICogdGVhbTogaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXIvY29tcG9uZW50cy9ibG9iL21haW4vc3JjL21hdGVyaWFsL3Rvb2x0aXAvdG9vbHRpcC50c1xuICogQ2hlY2sgdGhlbSBvdXQhIEdpdmUgdGhlbSBhIHRyeSEgTGVhdmUgYSBzdGFyISBUaGVpciB3b3JrIGlzIGluY3JlZGlibGUhXG4gKi9cblxuLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5pbXBvcnQgeyBBcmlhRGVzY3JpYmVyLCBGb2N1c01vbml0b3IgfSBmcm9tICdAYW5ndWxhci9jZGsvYTExeSc7XG5pbXBvcnQgeyBEaXJlY3Rpb25hbGl0eSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9iaWRpJztcbmltcG9ydCB7IGhhc01vZGlmaWVyS2V5IH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2tleWNvZGVzJztcbmltcG9ydCB7XG5cdHR5cGUgQ29ubmVjdGVkUG9zaXRpb24sXG5cdHR5cGUgQ29ubmVjdGlvblBvc2l0aW9uUGFpcixcblx0dHlwZSBGbGV4aWJsZUNvbm5lY3RlZFBvc2l0aW9uU3RyYXRlZ3ksXG5cdHR5cGUgSG9yaXpvbnRhbENvbm5lY3Rpb25Qb3MsXG5cdHR5cGUgT3JpZ2luQ29ubmVjdGlvblBvc2l0aW9uLFxuXHRPdmVybGF5LFxuXHR0eXBlIE92ZXJsYXlDb25uZWN0aW9uUG9zaXRpb24sXG5cdHR5cGUgT3ZlcmxheVJlZixcblx0U2Nyb2xsRGlzcGF0Y2hlcixcblx0dHlwZSBTY3JvbGxTdHJhdGVneSxcblx0dHlwZSBWZXJ0aWNhbENvbm5lY3Rpb25Qb3MsXG59IGZyb20gJ0Bhbmd1bGFyL2Nkay9vdmVybGF5JztcbmltcG9ydCB7IFBsYXRmb3JtLCBub3JtYWxpemVQYXNzaXZlTGlzdGVuZXJPcHRpb25zIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL3BsYXRmb3JtJztcbmltcG9ydCB7IENvbXBvbmVudFBvcnRhbCB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9wb3J0YWwnO1xuaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcblx0dHlwZSBBZnRlclZpZXdJbml0LFxuXHREaXJlY3RpdmUsXG5cdEVsZW1lbnRSZWYsXG5cdEluamVjdGlvblRva2VuLFxuXHRJbnB1dCxcblx0Tmdab25lLFxuXHR0eXBlIE9uRGVzdHJveSxcblx0dHlwZSBUZW1wbGF0ZVJlZixcblx0Vmlld0NvbnRhaW5lclJlZixcblx0Ym9vbGVhbkF0dHJpYnV0ZSxcblx0ZWZmZWN0LFxuXHRpbmplY3QsXG5cdGlzRGV2TW9kZSxcblx0bnVtYmVyQXR0cmlidXRlLFxuXHRzaWduYWwsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgYnJuRGV2TW9kZSB9IGZyb20gJ0BzcGFydGFuLW5nL3VpLWNvcmUnO1xuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFrZSwgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgQnJuVG9vbHRpcENvbnRlbnRDb21wb25lbnQgfSBmcm9tICcuL2Jybi10b29sdGlwLWNvbnRlbnQuY29tcG9uZW50JztcbmltcG9ydCB7IEJyblRvb2x0aXBEaXJlY3RpdmUgfSBmcm9tICcuL2Jybi10b29sdGlwLmRpcmVjdGl2ZSc7XG5cbmV4cG9ydCB0eXBlIFRvb2x0aXBQb3NpdGlvbiA9ICdsZWZ0JyB8ICdyaWdodCcgfCAnYWJvdmUnIHwgJ2JlbG93JyB8ICdiZWZvcmUnIHwgJ2FmdGVyJztcbmV4cG9ydCB0eXBlIFRvb2x0aXBUb3VjaEdlc3R1cmVzID0gJ2F1dG8nIHwgJ29uJyB8ICdvZmYnO1xuXG4vKiogVGltZSBpbiBtcyB0byB0aHJvdHRsZSByZXBvc2l0aW9uaW5nIGFmdGVyIHNjcm9sbCBldmVudHMuICovXG5leHBvcnQgY29uc3QgU0NST0xMX1RIUk9UVExFX01TID0gMjA7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRCcm5Ub29sdGlwSW52YWxpZFBvc2l0aW9uRXJyb3IocG9zaXRpb246IHN0cmluZykge1xuXHRyZXR1cm4gRXJyb3IoYFRvb2x0aXAgcG9zaXRpb24gXCIke3Bvc2l0aW9ufVwiIGlzIGludmFsaWQuYCk7XG59XG5cbi8qKiBJbmplY3Rpb24gdG9rZW4gdGhhdCBkZXRlcm1pbmVzIHRoZSBzY3JvbGwgaGFuZGxpbmcgd2hpbGUgYSB0b29sdGlwIGlzIHZpc2libGUuICovXG5leHBvcnQgY29uc3QgQlJOX1RPT0xUSVBfU0NST0xMX1NUUkFURUdZID0gbmV3IEluamVjdGlvblRva2VuPCgpID0+IFNjcm9sbFN0cmF0ZWd5PignYnJuLXRvb2x0aXAtc2Nyb2xsLXN0cmF0ZWd5Jyk7XG5leHBvcnQgY29uc3QgQlJOX1RPT0xUSVBfU0NST0xMX1NUUkFURUdZX0ZBQ1RPUllfUFJPVklERVIgPSB7XG5cdHByb3ZpZGU6IEJSTl9UT09MVElQX1NDUk9MTF9TVFJBVEVHWSxcblx0ZGVwczogW092ZXJsYXldLFxuXHR1c2VGYWN0b3J5OlxuXHRcdChvdmVybGF5OiBPdmVybGF5KTogKCgpID0+IFNjcm9sbFN0cmF0ZWd5KSA9PlxuXHRcdCgpID0+XG5cdFx0XHRvdmVybGF5LnNjcm9sbFN0cmF0ZWdpZXMucmVwb3NpdGlvbih7IHNjcm9sbFRocm90dGxlOiBTQ1JPTExfVEhST1RUTEVfTVMgfSksXG59O1xuXG5leHBvcnQgZnVuY3Rpb24gQlJOX1RPT0xUSVBfREVGQVVMVF9PUFRJT05TX0ZBQ1RPUlkoKTogQnJuVG9vbHRpcE9wdGlvbnMge1xuXHRyZXR1cm4ge1xuXHRcdHNob3dEZWxheTogMCxcblx0XHRoaWRlRGVsYXk6IDAsXG5cdFx0dG91Y2hlbmRIaWRlRGVsYXk6IDE1MDAsXG5cdH07XG59XG5cbmV4cG9ydCBjb25zdCBCUk5fVE9PTFRJUF9ERUZBVUxUX09QVElPTlMgPSBuZXcgSW5qZWN0aW9uVG9rZW48QnJuVG9vbHRpcE9wdGlvbnM+KCdtYXQtdG9vbHRpcC1kZWZhdWx0LW9wdGlvbnMnLCB7XG5cdHByb3ZpZGVkSW46ICdyb290Jyxcblx0ZmFjdG9yeTogQlJOX1RPT0xUSVBfREVGQVVMVF9PUFRJT05TX0ZBQ1RPUlksXG59KTtcblxuZXhwb3J0IGludGVyZmFjZSBCcm5Ub29sdGlwT3B0aW9ucyB7XG5cdC8qKiBEZWZhdWx0IGRlbGF5IHdoZW4gdGhlIHRvb2x0aXAgaXMgc2hvd24uICovXG5cdHNob3dEZWxheTogbnVtYmVyO1xuXHQvKiogRGVmYXVsdCBkZWxheSB3aGVuIHRoZSB0b29sdGlwIGlzIGhpZGRlbi4gKi9cblx0aGlkZURlbGF5OiBudW1iZXI7XG5cdC8qKiBEZWZhdWx0IGRlbGF5IHdoZW4gaGlkaW5nIHRoZSB0b29sdGlwIG9uIGEgdG91Y2ggZGV2aWNlLiAqL1xuXHR0b3VjaGVuZEhpZGVEZWxheTogbnVtYmVyO1xuXHQvKiogRGVmYXVsdCB0b3VjaCBnZXN0dXJlIGhhbmRsaW5nIGZvciB0b29sdGlwcy4gKi9cblx0dG91Y2hHZXN0dXJlcz86IFRvb2x0aXBUb3VjaEdlc3R1cmVzO1xuXHQvKiogRGVmYXVsdCBwb3NpdGlvbiBmb3IgdG9vbHRpcHMuICovXG5cdHBvc2l0aW9uPzogVG9vbHRpcFBvc2l0aW9uO1xuXHQvKipcblx0ICogRGVmYXVsdCB2YWx1ZSBmb3Igd2hldGhlciB0b29sdGlwcyBzaG91bGQgYmUgcG9zaXRpb25lZCBuZWFyIHRoZSBjbGljayBvciB0b3VjaCBvcmlnaW5cblx0ICogaW5zdGVhZCBvZiBvdXRzaWRlIHRoZSBlbGVtZW50IGJvdW5kaW5nIGJveC5cblx0ICovXG5cdHBvc2l0aW9uQXRPcmlnaW4/OiBib29sZWFuO1xuXHQvKiogRGlzYWJsZXMgdGhlIGFiaWxpdHkgZm9yIHRoZSB1c2VyIHRvIGludGVyYWN0IHdpdGggdGhlIHRvb2x0aXAgZWxlbWVudC4gKi9cblx0ZGlzYWJsZVRvb2x0aXBJbnRlcmFjdGl2aXR5PzogYm9vbGVhbjtcbn1cblxuY29uc3QgUEFORUxfQ0xBU1MgPSAndG9vbHRpcC1wYW5lbCc7XG5cbi8qKiBPcHRpb25zIHVzZWQgdG8gYmluZCBwYXNzaXZlIGV2ZW50IGxpc3RlbmVycy4gKi9cbmNvbnN0IHBhc3NpdmVMaXN0ZW5lck9wdGlvbnMgPSBub3JtYWxpemVQYXNzaXZlTGlzdGVuZXJPcHRpb25zKHsgcGFzc2l2ZTogdHJ1ZSB9KTtcblxuLyoqXG4gKiBUaW1lIGJldHdlZW4gdGhlIHVzZXIgcHV0dGluZyB0aGUgcG9pbnRlciBvbiBhIHRvb2x0aXBcbiAqIHRyaWdnZXIgYW5kIHRoZSBsb25nIHByZXNzIGV2ZW50IGJlaW5nIGZpcmVkLlxuICovXG5jb25zdCBMT05HUFJFU1NfREVMQVkgPSA1MDA7XG5cbi8vIFRoZXNlIGNvbnN0YW50cyB3ZXJlIHRha2VuIGZyb20gTURDJ3MgYG51bWJlcnNgIG9iamVjdC5cbmNvbnN0IE1JTl9WSUVXUE9SVF9UT09MVElQX1RIUkVTSE9MRCA9IDg7XG5jb25zdCBVTkJPVU5ERURfQU5DSE9SX0dBUCA9IDg7XG5cbkBEaXJlY3RpdmUoe1xuXHRzZWxlY3RvcjogJ1ticm5Ub29sdGlwVHJpZ2dlcl0nLFxuXHRzdGFuZGFsb25lOiB0cnVlLFxuXHRleHBvcnRBczogJ2JyblRvb2x0aXBUcmlnZ2VyJyxcblx0cHJvdmlkZXJzOiBbQlJOX1RPT0xUSVBfU0NST0xMX1NUUkFURUdZX0ZBQ1RPUllfUFJPVklERVJdLFxuXHRob3N0OiB7XG5cdFx0Y2xhc3M6ICdicm4tdG9vbHRpcC10cmlnZ2VyJyxcblx0XHQnW2NsYXNzLmJybi10b29sdGlwLWRpc2FibGVkXSc6ICdkaXNhYmxlZCcsXG5cdH0sXG59KVxuZXhwb3J0IGNsYXNzIEJyblRvb2x0aXBUcmlnZ2VyRGlyZWN0aXZlIGltcGxlbWVudHMgT25EZXN0cm95LCBBZnRlclZpZXdJbml0IHtcblx0cHJpdmF0ZSByZWFkb25seSBfdG9vbHRpcERpcmVjdGl2ZSA9IGluamVjdChCcm5Ub29sdGlwRGlyZWN0aXZlLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuXHRwcml2YXRlIHJlYWRvbmx5IF90b29sdGlwQ29tcG9uZW50ID0gQnJuVG9vbHRpcENvbnRlbnRDb21wb25lbnQ7XG5cdHByaXZhdGUgcmVhZG9ubHkgX2Nzc0NsYXNzUHJlZml4OiBzdHJpbmcgPSAnYnJuJztcblx0cHJpdmF0ZSByZWFkb25seSBfZGVzdHJveWVkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblx0cHJpdmF0ZSByZWFkb25seSBfcGFzc2l2ZUxpc3RlbmVyczogKHJlYWRvbmx5IFtzdHJpbmcsIEV2ZW50TGlzdGVuZXJPckV2ZW50TGlzdGVuZXJPYmplY3RdKVtdID0gW107XG5cdHByaXZhdGUgcmVhZG9ubHkgX2RlZmF1bHRPcHRpb25zID0gaW5qZWN0KEJSTl9UT09MVElQX0RFRkFVTFRfT1BUSU9OUywgeyBvcHRpb25hbDogdHJ1ZSB9KTtcblx0cHJpdmF0ZSByZWFkb25seSBfb3ZlcmxheSA9IGluamVjdChPdmVybGF5KTtcblx0cHJpdmF0ZSByZWFkb25seSBfZWxlbWVudFJlZiA9IGluamVjdChFbGVtZW50UmVmPEhUTUxFbGVtZW50Pik7XG5cdHByaXZhdGUgcmVhZG9ubHkgX3Njcm9sbERpc3BhdGNoZXIgPSBpbmplY3QoU2Nyb2xsRGlzcGF0Y2hlcik7XG5cdHByaXZhdGUgcmVhZG9ubHkgX3ZpZXdDb250YWluZXJSZWYgPSBpbmplY3QoVmlld0NvbnRhaW5lclJlZik7XG5cdHByaXZhdGUgcmVhZG9ubHkgX25nWm9uZSA9IGluamVjdChOZ1pvbmUpO1xuXHRwcml2YXRlIHJlYWRvbmx5IF9wbGF0Zm9ybSA9IGluamVjdChQbGF0Zm9ybSk7XG5cdHByaXZhdGUgcmVhZG9ubHkgX2FyaWFEZXNjcmliZXIgPSBpbmplY3QoQXJpYURlc2NyaWJlcik7XG5cdHByaXZhdGUgcmVhZG9ubHkgX2ZvY3VzTW9uaXRvciA9IGluamVjdChGb2N1c01vbml0b3IpO1xuXHRwcml2YXRlIHJlYWRvbmx5IF9kaXIgPSBpbmplY3QoRGlyZWN0aW9uYWxpdHkpO1xuXHRwcml2YXRlIHJlYWRvbmx5IF9zY3JvbGxTdHJhdGVneSA9IGluamVjdChCUk5fVE9PTFRJUF9TQ1JPTExfU1RSQVRFR1kpO1xuXHRwcml2YXRlIHJlYWRvbmx5IF9kb2N1bWVudCA9IGluamVjdChET0NVTUVOVCk7XG5cblx0cHJpdmF0ZSBfcG9ydGFsPzogQ29tcG9uZW50UG9ydGFsPEJyblRvb2x0aXBDb250ZW50Q29tcG9uZW50Pjtcblx0cHJpdmF0ZSBfdmlld0luaXRpYWxpemVkID0gZmFsc2U7XG5cdHByaXZhdGUgX3BvaW50ZXJFeGl0RXZlbnRzSW5pdGlhbGl6ZWQgPSBmYWxzZTtcblx0cHJpdmF0ZSByZWFkb25seSBfdmlld3BvcnRNYXJnaW4gPSA4O1xuXHRwcml2YXRlIF9jdXJyZW50UG9zaXRpb24/OiBUb29sdGlwUG9zaXRpb247XG5cdHByaXZhdGUgX3RvdWNoc3RhcnRUaW1lb3V0PzogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD47XG5cblx0cHJpdmF0ZSBfb3ZlcmxheVJlZjogT3ZlcmxheVJlZiB8IG51bGwgPSBudWxsO1xuXHRwcml2YXRlIF90b29sdGlwSW5zdGFuY2U6IEJyblRvb2x0aXBDb250ZW50Q29tcG9uZW50IHwgbnVsbCA9IG51bGw7XG5cblx0LyoqIEFsbG93cyB0aGUgdXNlciB0byBkZWZpbmUgdGhlIHBvc2l0aW9uIG9mIHRoZSB0b29sdGlwIHJlbGF0aXZlIHRvIHRoZSBwYXJlbnQgZWxlbWVudCAqL1xuXHRwcml2YXRlIHJlYWRvbmx5IF9wb3NpdGlvbiA9IHNpZ25hbDxUb29sdGlwUG9zaXRpb24+KCdhYm92ZScpO1xuXHRASW5wdXQoKVxuXHRwdWJsaWMgZ2V0IHBvc2l0aW9uKCk6IFRvb2x0aXBQb3NpdGlvbiB7XG5cdFx0cmV0dXJuIHRoaXMuX3Bvc2l0aW9uKCk7XG5cdH1cblxuXHRwdWJsaWMgc2V0IHBvc2l0aW9uKHZhbHVlOiBUb29sdGlwUG9zaXRpb24pIHtcblx0XHRpZiAodmFsdWUgIT09IHRoaXMuX3Bvc2l0aW9uKCkpIHtcblx0XHRcdHRoaXMuX3Bvc2l0aW9uLnNldCh2YWx1ZSk7XG5cblx0XHRcdGlmICh0aGlzLl9vdmVybGF5UmVmKSB7XG5cdFx0XHRcdHRoaXMuX3VwZGF0ZVBvc2l0aW9uKHRoaXMuX292ZXJsYXlSZWYpO1xuXHRcdFx0XHR0aGlzLl90b29sdGlwSW5zdGFuY2U/LnNob3coMCk7XG5cdFx0XHRcdHRoaXMuX292ZXJsYXlSZWYudXBkYXRlUG9zaXRpb24oKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogV2hldGhlciB0b29sdGlwIHNob3VsZCBiZSByZWxhdGl2ZSB0byB0aGUgY2xpY2sgb3IgdG91Y2ggb3JpZ2luXG5cdCAqIGluc3RlYWQgb2Ygb3V0c2lkZSB0aGUgZWxlbWVudCBib3VuZGluZyBib3guXG5cdCAqL1xuXHRwcml2YXRlIHJlYWRvbmx5IF9wb3NpdGlvbkF0T3JpZ2luID0gc2lnbmFsKGZhbHNlKTtcblx0QElucHV0KHsgdHJhbnNmb3JtOiBib29sZWFuQXR0cmlidXRlIH0pXG5cdHB1YmxpYyBnZXQgcG9zaXRpb25BdE9yaWdpbigpOiBib29sZWFuIHtcblx0XHRyZXR1cm4gdGhpcy5fcG9zaXRpb25BdE9yaWdpbigpO1xuXHR9XG5cblx0cHVibGljIHNldCBwb3NpdGlvbkF0T3JpZ2luKHZhbHVlOiBib29sZWFuKSB7XG5cdFx0dGhpcy5fcG9zaXRpb25BdE9yaWdpbi5zZXQodmFsdWUpO1xuXHRcdHRoaXMuX2RldGFjaCgpO1xuXHRcdHRoaXMuX292ZXJsYXlSZWYgPSBudWxsO1xuXHR9XG5cblx0LyoqIERpc2FibGVzIHRoZSBkaXNwbGF5IG9mIHRoZSB0b29sdGlwLiAqL1xuXHRwcml2YXRlIHJlYWRvbmx5IF9kaXNhYmxlZCA9IHNpZ25hbChmYWxzZSk7XG5cdEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSwgYWxpYXM6ICdicm5Ub29sdGlwRGlzYWJsZWQnIH0pXG5cdHB1YmxpYyBnZXQgZGlzYWJsZWQoKTogYm9vbGVhbiB7XG5cdFx0cmV0dXJuIHRoaXMuX2Rpc2FibGVkKCk7XG5cdH1cblxuXHRwdWJsaWMgc2V0IGRpc2FibGVkKHZhbHVlOiBib29sZWFuKSB7XG5cdFx0dGhpcy5fZGlzYWJsZWQuc2V0KHZhbHVlKTtcblxuXHRcdC8vIElmIHRvb2x0aXAgaXMgZGlzYWJsZWQsIGhpZGUgaW1tZWRpYXRlbHkuXG5cdFx0aWYgKHZhbHVlKSB7XG5cdFx0XHR0aGlzLmhpZGUoMCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuX3NldHVwUG9pbnRlckVudGVyRXZlbnRzSWZOZWVkZWQoKTtcblx0XHR9XG5cdH1cblxuXHQvKiogVGhlIGRlZmF1bHQgZGVsYXkgaW4gbXMgYmVmb3JlIHNob3dpbmcgdGhlIHRvb2x0aXAgYWZ0ZXIgc2hvdyBpcyBjYWxsZWQgKi9cblx0cHJpdmF0ZSByZWFkb25seSBfc2hvd0RlbGF5ID0gc2lnbmFsKDApO1xuXHRASW5wdXQoeyB0cmFuc2Zvcm06IG51bWJlckF0dHJpYnV0ZSB9KVxuXHRwdWJsaWMgZ2V0IHNob3dEZWxheSgpOiBudW1iZXIge1xuXHRcdHJldHVybiB0aGlzLl9zaG93RGVsYXkoKTtcblx0fVxuXG5cdHB1YmxpYyBzZXQgc2hvd0RlbGF5KHZhbHVlOiBudW1iZXIpIHtcblx0XHR0aGlzLl9zaG93RGVsYXkuc2V0KHZhbHVlKTtcblx0fVxuXG5cdC8qKiBUaGUgZGVmYXVsdCBkZWxheSBpbiBtcyBiZWZvcmUgaGlkaW5nIHRoZSB0b29sdGlwIGFmdGVyIGhpZGUgaXMgY2FsbGVkICovXG5cdHByaXZhdGUgcmVhZG9ubHkgX2hpZGVEZWxheSA9IHNpZ25hbCgwKTtcblx0QElucHV0KHsgdHJhbnNmb3JtOiBudW1iZXJBdHRyaWJ1dGUgfSlcblx0cHVibGljIGdldCBoaWRlRGVsYXkoKTogbnVtYmVyIHtcblx0XHRyZXR1cm4gdGhpcy5faGlkZURlbGF5KCk7XG5cdH1cblxuXHRwdWJsaWMgc2V0IGhpZGVEZWxheSh2YWx1ZTogbnVtYmVyKSB7XG5cdFx0dGhpcy5faGlkZURlbGF5LnNldCh2YWx1ZSk7XG5cblx0XHRpZiAodGhpcy5fdG9vbHRpcEluc3RhbmNlKSB7XG5cdFx0XHR0aGlzLl90b29sdGlwSW5zdGFuY2UuX21vdXNlTGVhdmVIaWRlRGVsYXkgPSB0aGlzLl9oaWRlRGVsYXkoKTtcblx0XHR9XG5cdH1cblxuXHQvKiogVGhlIGRlZmF1bHQgZHVyYXRpb24gaW4gbXMgdGhhdCBleGl0IGFuaW1hdGlvbiB0YWtlcyBiZWZvcmUgaGlkaW5nICovXG5cdHByaXZhdGUgcmVhZG9ubHkgX2V4aXRBbmltYXRpb25EdXJhdGlvbiA9IHNpZ25hbCgwKTtcblx0QElucHV0KHsgdHJhbnNmb3JtOiBudW1iZXJBdHRyaWJ1dGUgfSlcblx0cHVibGljIGdldCBleGl0QW5pbWF0aW9uRHVyYXRpb24oKTogbnVtYmVyIHtcblx0XHRyZXR1cm4gdGhpcy5fZXhpdEFuaW1hdGlvbkR1cmF0aW9uKCk7XG5cdH1cblxuXHRwdWJsaWMgc2V0IGV4aXRBbmltYXRpb25EdXJhdGlvbih2YWx1ZTogbnVtYmVyKSB7XG5cdFx0dGhpcy5fZXhpdEFuaW1hdGlvbkR1cmF0aW9uLnNldCh2YWx1ZSk7XG5cblx0XHRpZiAodGhpcy5fdG9vbHRpcEluc3RhbmNlKSB7XG5cdFx0XHR0aGlzLl90b29sdGlwSW5zdGFuY2UuX2V4aXRBbmltYXRpb25EdXJhdGlvbiA9IHRoaXMuX2V4aXRBbmltYXRpb25EdXJhdGlvbigpO1xuXHRcdH1cblx0fVxuXG5cdC8qKiBUaGUgZGVmYXVsdCBkZWxheSBpbiBtcyBiZWZvcmUgaGlkaW5nIHRoZSB0b29sdGlwIGFmdGVyIGhpZGUgaXMgY2FsbGVkICovXG5cdHByaXZhdGUgcmVhZG9ubHkgX3Rvb2x0aXBDb250ZW50Q2xhc3NlcyA9IHNpZ25hbCgnJyk7XG5cdEBJbnB1dCgpXG5cdHB1YmxpYyBnZXQgdG9vbHRpcENvbnRlbnRDbGFzc2VzKCk6IHN0cmluZyB7XG5cdFx0cmV0dXJuIHRoaXMuX3Rvb2x0aXBDb250ZW50Q2xhc3NlcygpO1xuXHR9XG5cblx0cHVibGljIHNldCB0b29sdGlwQ29udGVudENsYXNzZXModmFsdWU6IHN0cmluZyB8IG51bGwgfCB1bmRlZmluZWQpIHtcblx0XHR0aGlzLl90b29sdGlwQ29udGVudENsYXNzZXMuc2V0KHZhbHVlID8/ICcnKTtcblxuXHRcdGlmICh0aGlzLl90b29sdGlwSW5zdGFuY2UpIHtcblx0XHRcdHRoaXMuX3Rvb2x0aXBJbnN0YW5jZS5fdG9vbHRpcENsYXNzZXMuc2V0KHZhbHVlID8/ICcnKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogSG93IHRvdWNoIGdlc3R1cmVzIHNob3VsZCBiZSBoYW5kbGVkIGJ5IHRoZSB0b29sdGlwLiBPbiB0b3VjaCBkZXZpY2VzIHRoZSB0b29sdGlwIGRpcmVjdGl2ZVxuXHQgKiB1c2VzIGEgbG9uZyBwcmVzcyBnZXN0dXJlIHRvIHNob3cgYW5kIGhpZGUsIGhvd2V2ZXIgaXQgY2FuIGNvbmZsaWN0IHdpdGggdGhlIG5hdGl2ZSBicm93c2VyXG5cdCAqIGdlc3R1cmVzLiBUbyB3b3JrIGFyb3VuZCB0aGUgY29uZmxpY3QsIEFuZ3VsYXIgTWF0ZXJpYWwgZGlzYWJsZXMgbmF0aXZlIGdlc3R1cmVzIG9uIHRoZVxuXHQgKiB0cmlnZ2VyLCBidXQgdGhhdCBtaWdodCBub3QgYmUgZGVzaXJhYmxlIG9uIHBhcnRpY3VsYXIgZWxlbWVudHMgKGUuZy4gaW5wdXRzIGFuZCBkcmFnZ2FibGVcblx0ICogZWxlbWVudHMpLiBUaGUgZGlmZmVyZW50IHZhbHVlcyBmb3IgdGhpcyBvcHRpb24gY29uZmlndXJlIHRoZSB0b3VjaCBldmVudCBoYW5kbGluZyBhcyBmb2xsb3dzOlxuXHQgKiAtIGBhdXRvYCAtIEVuYWJsZXMgdG91Y2ggZ2VzdHVyZXMgZm9yIGFsbCBlbGVtZW50cywgYnV0IHRyaWVzIHRvIGF2b2lkIGNvbmZsaWN0cyB3aXRoIG5hdGl2ZVxuXHQgKiAgIGJyb3dzZXIgZ2VzdHVyZXMgb24gcGFydGljdWxhciBlbGVtZW50cy4gSW4gcGFydGljdWxhciwgaXQgYWxsb3dzIHRleHQgc2VsZWN0aW9uIG9uIGlucHV0c1xuXHQgKiAgIGFuZCB0ZXh0YXJlYXMsIGFuZCBwcmVzZXJ2ZXMgdGhlIG5hdGl2ZSBicm93c2VyIGRyYWdnaW5nIG9uIGVsZW1lbnRzIG1hcmtlZCBhcyBgZHJhZ2dhYmxlYC5cblx0ICogLSBgb25gIC0gRW5hYmxlcyB0b3VjaCBnZXN0dXJlcyBmb3IgYWxsIGVsZW1lbnRzIGFuZCBkaXNhYmxlcyBuYXRpdmVcblx0ICogICBicm93c2VyIGdlc3R1cmVzIHdpdGggbm8gZXhjZXB0aW9ucy5cblx0ICogLSBgb2ZmYCAtIERpc2FibGVzIHRvdWNoIGdlc3R1cmVzLiBOb3RlIHRoYXQgdGhpcyB3aWxsIHByZXZlbnQgdGhlIHRvb2x0aXAgZnJvbVxuXHQgKiAgIHNob3dpbmcgb24gdG91Y2ggZGV2aWNlcy5cblx0ICovXG5cdHByaXZhdGUgcmVhZG9ubHkgX3RvdWNoR2VzdHVyZXMgPSBzaWduYWw8VG9vbHRpcFRvdWNoR2VzdHVyZXM+KCdhdXRvJyk7XG5cdEBJbnB1dCgpXG5cdHB1YmxpYyBzZXQgdG91Y2hHZXN0dXJlcyh2YWx1ZTogVG9vbHRpcFRvdWNoR2VzdHVyZXMpIHtcblx0XHR0aGlzLl90b3VjaEdlc3R1cmVzLnNldCh2YWx1ZSk7XG5cdH1cblxuXHRwdWJsaWMgZ2V0IHRvdWNoR2VzdHVyZXMoKSB7XG5cdFx0cmV0dXJuIHRoaXMuX3RvdWNoR2VzdHVyZXMoKTtcblx0fVxuXG5cdC8qKiBUaGUgbWVzc2FnZSB0byBiZSB1c2VkIHRvIGRlc2NyaWJlIHRoZSBhcmlhIGluIHRoZSB0b29sdGlwICovXG5cdHByaXZhdGUgX2FyaWFEZXNjcmliZWRCeSA9ICcnO1xuXHRASW5wdXQoJ2FyaWEtZGVzY3JpYmVkYnknKVxuXHRwdWJsaWMgZ2V0IGFyaWFEZXNjcmliZWRCeSgpIHtcblx0XHRyZXR1cm4gdGhpcy5fYXJpYURlc2NyaWJlZEJ5O1xuXHR9XG5cblx0cHVibGljIHNldCBhcmlhRGVzY3JpYmVkQnkodmFsdWU6IHN0cmluZykge1xuXHRcdHRoaXMuX2FyaWFEZXNjcmliZXIucmVtb3ZlRGVzY3JpcHRpb24odGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCB0aGlzLl9hcmlhRGVzY3JpYmVkQnksICd0b29sdGlwJyk7XG5cblx0XHQvLyBJZiB0aGUgbWVzc2FnZSBpcyBub3QgYSBzdHJpbmcgKGUuZy4gbnVtYmVyKSwgY29udmVydCBpdCB0byBhIHN0cmluZyBhbmQgdHJpbSBpdC5cblx0XHQvLyBNdXN0IGNvbnZlcnQgd2l0aCBgU3RyaW5nKHZhbHVlKWAsIG5vdCBgJHt2YWx1ZX1gLCBvdGhlcndpc2UgQ2xvc3VyZSBDb21waWxlciBvcHRpbWlzZXNcblx0XHQvLyBhd2F5IHRoZSBzdHJpbmctY29udmVyc2lvbjogaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXIvY29tcG9uZW50cy9pc3N1ZXMvMjA2ODRcblx0XHR0aGlzLl9hcmlhRGVzY3JpYmVkQnkgPSB2YWx1ZSAhPT0gbnVsbCA/IFN0cmluZyh2YWx1ZSkudHJpbSgpIDogJyc7XG5cblx0XHRpZiAodGhpcy5fYXJpYURlc2NyaWJlZEJ5ICYmICF0aGlzLl9pc1Rvb2x0aXBWaXNpYmxlKCkpIHtcblx0XHRcdHRoaXMuX25nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG5cdFx0XHRcdC8vIFRoZSBgQXJpYURlc2NyaWJlcmAgaGFzIHNvbWUgZnVuY3Rpb25hbGl0eSB0aGF0IGF2b2lkcyBhZGRpbmcgYSBkZXNjcmlwdGlvbiBpZiBpdCdzIHRoZVxuXHRcdFx0XHQvLyBzYW1lIGFzIHRoZSBgYXJpYS1sYWJlbGAgb2YgYW4gZWxlbWVudCwgaG93ZXZlciB3ZSBjYW4ndCBrbm93IHdoZXRoZXIgdGhlIHRvb2x0aXAgdHJpZ2dlclxuXHRcdFx0XHQvLyBoYXMgYSBkYXRhLWJvdW5kIGBhcmlhLWxhYmVsYCBvciB3aGVuIGl0J2xsIGJlIHNldCBmb3IgdGhlIGZpcnN0IHRpbWUuIFdlIGNhbiBhdm9pZCB0aGVcblx0XHRcdFx0Ly8gaXNzdWUgYnkgZGVmZXJyaW5nIHRoZSBkZXNjcmlwdGlvbiBieSBhIHRpY2sgc28gQW5ndWxhciBoYXMgdGltZSB0byBzZXQgdGhlIGBhcmlhLWxhYmVsYC5cblx0XHRcdFx0UHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5fYXJpYURlc2NyaWJlci5kZXNjcmliZSh0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsIHRoaXMuX2FyaWFEZXNjcmliZWRCeSwgJ3Rvb2x0aXAnKTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9KTtcblx0XHR9XG5cdH1cblxuXHQvKiogVGhlIGNvbnRlbnQgdG8gYmUgZGlzcGxheWVkIGluIHRoZSB0b29sdGlwICovXG5cdHByaXZhdGUgX2NvbnRlbnQ6IHN0cmluZyB8IFRlbXBsYXRlUmVmPHVua25vd24+IHwgbnVsbCA9IG51bGw7XG5cdEBJbnB1dCgnYnJuVG9vbHRpcFRyaWdnZXInKVxuXHRwdWJsaWMgZ2V0IGNvbnRlbnQoKSB7XG5cdFx0cmV0dXJuIHRoaXMuX2NvbnRlbnQ7XG5cdH1cblxuXHRwdWJsaWMgc2V0IGNvbnRlbnQodmFsdWU6IHN0cmluZyB8IFRlbXBsYXRlUmVmPHVua25vd24+IHwgbnVsbCkge1xuXHRcdHRoaXMuX2NvbnRlbnQgPSB2YWx1ZTtcblxuXHRcdGlmICghdGhpcy5fY29udGVudCAmJiB0aGlzLl9pc1Rvb2x0aXBWaXNpYmxlKCkpIHtcblx0XHRcdHRoaXMuaGlkZSgwKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5fc2V0dXBQb2ludGVyRW50ZXJFdmVudHNJZk5lZWRlZCgpO1xuXHRcdFx0dGhpcy5fdXBkYXRlVG9vbHRpcENvbnRlbnQoKTtcblx0XHR9XG5cdH1cblxuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHRpZiAodGhpcy5fZGVmYXVsdE9wdGlvbnMpIHtcblx0XHRcdHRoaXMuX3Nob3dEZWxheS5zZXQodGhpcy5fZGVmYXVsdE9wdGlvbnMuc2hvd0RlbGF5KTtcblx0XHRcdHRoaXMuX2hpZGVEZWxheS5zZXQodGhpcy5fZGVmYXVsdE9wdGlvbnMuaGlkZURlbGF5KTtcblxuXHRcdFx0aWYgKHRoaXMuX2RlZmF1bHRPcHRpb25zLnBvc2l0aW9uKSB7XG5cdFx0XHRcdHRoaXMucG9zaXRpb24gPSB0aGlzLl9kZWZhdWx0T3B0aW9ucy5wb3NpdGlvbjtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHRoaXMuX2RlZmF1bHRPcHRpb25zLnBvc2l0aW9uQXRPcmlnaW4pIHtcblx0XHRcdFx0dGhpcy5wb3NpdGlvbkF0T3JpZ2luID0gdGhpcy5fZGVmYXVsdE9wdGlvbnMucG9zaXRpb25BdE9yaWdpbjtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHRoaXMuX2RlZmF1bHRPcHRpb25zLnRvdWNoR2VzdHVyZXMpIHtcblx0XHRcdFx0dGhpcy50b3VjaEdlc3R1cmVzID0gdGhpcy5fZGVmYXVsdE9wdGlvbnMudG91Y2hHZXN0dXJlcztcblx0XHRcdH1cblx0XHR9XG5cblx0XHR0aGlzLl9kaXIuY2hhbmdlLnBpcGUodGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3llZCkpLnN1YnNjcmliZSgoKSA9PiB7XG5cdFx0XHRpZiAodGhpcy5fb3ZlcmxheVJlZikge1xuXHRcdFx0XHR0aGlzLl91cGRhdGVQb3NpdGlvbih0aGlzLl9vdmVybGF5UmVmKTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdHRoaXMuX3ZpZXdwb3J0TWFyZ2luID0gTUlOX1ZJRVdQT1JUX1RPT0xUSVBfVEhSRVNIT0xEO1xuXG5cdFx0aWYgKHRoaXMuX3Rvb2x0aXBEaXJlY3RpdmUpIHtcblx0XHRcdGVmZmVjdCgoKSA9PiB7XG5cdFx0XHRcdGlmICh0aGlzLl90b29sdGlwRGlyZWN0aXZlKSB7XG5cdFx0XHRcdFx0dGhpcy5jb250ZW50ID0gdGhpcy5fdG9vbHRpcERpcmVjdGl2ZS50b29sdGlwVGVtcGxhdGUoKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fVxuXHR9XG5cblx0bmdBZnRlclZpZXdJbml0KCkge1xuXHRcdC8vIFRoaXMgbmVlZHMgdG8gaGFwcGVuIGFmdGVyIHZpZXcgaW5pdCBzbyB0aGUgaW5pdGlhbCB2YWx1ZXMgZm9yIGFsbCBpbnB1dHMgaGF2ZSBiZWVuIHNldC5cblx0XHR0aGlzLl92aWV3SW5pdGlhbGl6ZWQgPSB0cnVlO1xuXHRcdHRoaXMuX3NldHVwUG9pbnRlckVudGVyRXZlbnRzSWZOZWVkZWQoKTtcblxuXHRcdHRoaXMuX2ZvY3VzTW9uaXRvclxuXHRcdFx0Lm1vbml0b3IodGhpcy5fZWxlbWVudFJlZilcblx0XHRcdC5waXBlKHRha2VVbnRpbCh0aGlzLl9kZXN0cm95ZWQpKVxuXHRcdFx0LnN1YnNjcmliZSgob3JpZ2luKSA9PiB7XG5cdFx0XHRcdC8vIE5vdGUgdGhhdCB0aGUgZm9jdXMgbW9uaXRvciBydW5zIG91dHNpZGUgdGhlIEFuZ3VsYXIgem9uZS5cblx0XHRcdFx0aWYgKCFvcmlnaW4pIHtcblx0XHRcdFx0XHR0aGlzLl9uZ1pvbmUucnVuKCgpID0+IHRoaXMuaGlkZSgwKSk7XG5cdFx0XHRcdH0gZWxzZSBpZiAob3JpZ2luID09PSAna2V5Ym9hcmQnKSB7XG5cdFx0XHRcdFx0dGhpcy5fbmdab25lLnJ1bigoKSA9PiB0aGlzLnNob3coKSk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXG5cdFx0aWYgKGJybkRldk1vZGUgJiYgIXRoaXMuX2FyaWFEZXNjcmliZWRCeSkge1xuXHRcdFx0Y29uc29sZS53YXJuKCdCcm5Ub29sdGlwOiBcImFyaWEtZGVzY3JpYmVkYnlcIiBhdHRyaWJ1dGUgaXMgcmVxdWlyZWQgZm9yIGFjY2Vzc2liaWxpdHknKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogRGlzcG9zZSB0aGUgdG9vbHRpcCB3aGVuIGRlc3Ryb3llZC5cblx0ICovXG5cdG5nT25EZXN0cm95KCkge1xuXHRcdGNvbnN0IG5hdGl2ZUVsZW1lbnQgPSB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XG5cblx0XHRjbGVhclRpbWVvdXQodGhpcy5fdG91Y2hzdGFydFRpbWVvdXQpO1xuXG5cdFx0aWYgKHRoaXMuX292ZXJsYXlSZWYpIHtcblx0XHRcdHRoaXMuX292ZXJsYXlSZWYuZGlzcG9zZSgpO1xuXHRcdFx0dGhpcy5fdG9vbHRpcEluc3RhbmNlID0gbnVsbDtcblx0XHR9XG5cblx0XHQvLyBDbGVhbiB1cCB0aGUgZXZlbnQgbGlzdGVuZXJzIHNldCBpbiB0aGUgY29uc3RydWN0b3Jcblx0XHR0aGlzLl9wYXNzaXZlTGlzdGVuZXJzLmZvckVhY2goKFtldmVudCwgbGlzdGVuZXJdKSA9PlxuXHRcdFx0bmF0aXZlRWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lciwgcGFzc2l2ZUxpc3RlbmVyT3B0aW9ucyksXG5cdFx0KTtcblx0XHR0aGlzLl9wYXNzaXZlTGlzdGVuZXJzLmxlbmd0aCA9IDA7XG5cblx0XHR0aGlzLl9kZXN0cm95ZWQubmV4dCgpO1xuXHRcdHRoaXMuX2Rlc3Ryb3llZC5jb21wbGV0ZSgpO1xuXG5cdFx0dGhpcy5fYXJpYURlc2NyaWJlci5yZW1vdmVEZXNjcmlwdGlvbihuYXRpdmVFbGVtZW50LCB0aGlzLl9hcmlhRGVzY3JpYmVkQnksICd0b29sdGlwJyk7XG5cdFx0dGhpcy5fZm9jdXNNb25pdG9yLnN0b3BNb25pdG9yaW5nKG5hdGl2ZUVsZW1lbnQpO1xuXHR9XG5cblx0LyoqIFNob3dzIHRoZSB0b29sdGlwIGFmdGVyIHRoZSBkZWxheSBpbiBtcywgZGVmYXVsdHMgdG8gdG9vbHRpcC1kZWxheS1zaG93IG9yIDBtcyBpZiBubyBpbnB1dCAqL1xuXHRzaG93KGRlbGF5OiBudW1iZXIgPSB0aGlzLnNob3dEZWxheSwgb3JpZ2luPzogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9KTogdm9pZCB7XG5cdFx0aWYgKHRoaXMuZGlzYWJsZWQgfHwgdGhpcy5faXNUb29sdGlwVmlzaWJsZSgpKSB7XG5cdFx0XHR0aGlzLl90b29sdGlwSW5zdGFuY2U/Ll9jYW5jZWxQZW5kaW5nQW5pbWF0aW9ucygpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGNvbnN0IG92ZXJsYXlSZWYgPSB0aGlzLl9jcmVhdGVPdmVybGF5KG9yaWdpbik7XG5cdFx0dGhpcy5fZGV0YWNoKCk7XG5cdFx0dGhpcy5fcG9ydGFsID0gdGhpcy5fcG9ydGFsIHx8IG5ldyBDb21wb25lbnRQb3J0YWwodGhpcy5fdG9vbHRpcENvbXBvbmVudCwgdGhpcy5fdmlld0NvbnRhaW5lclJlZik7XG5cdFx0Y29uc3QgaW5zdGFuY2UgPSAodGhpcy5fdG9vbHRpcEluc3RhbmNlID0gb3ZlcmxheVJlZi5hdHRhY2godGhpcy5fcG9ydGFsKS5pbnN0YW5jZSk7XG5cdFx0aW5zdGFuY2UuX3RyaWdnZXJFbGVtZW50ID0gdGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xuXHRcdGluc3RhbmNlLl9tb3VzZUxlYXZlSGlkZURlbGF5ID0gdGhpcy5faGlkZURlbGF5KCk7XG5cdFx0aW5zdGFuY2UuX3Rvb2x0aXBDbGFzc2VzLnNldCh0aGlzLl90b29sdGlwQ29udGVudENsYXNzZXMoKSk7XG5cdFx0aW5zdGFuY2UuX2V4aXRBbmltYXRpb25EdXJhdGlvbiA9IHRoaXMuX2V4aXRBbmltYXRpb25EdXJhdGlvbigpO1xuXHRcdGluc3RhbmNlLnNpZGUuc2V0KHRoaXMuX2N1cnJlbnRQb3NpdGlvbiA/PyAnYWJvdmUnKTtcblx0XHRpbnN0YW5jZS5hZnRlckhpZGRlbi5waXBlKHRha2VVbnRpbCh0aGlzLl9kZXN0cm95ZWQpKS5zdWJzY3JpYmUoKCkgPT4gdGhpcy5fZGV0YWNoKCkpO1xuXHRcdHRoaXMuX3VwZGF0ZVRvb2x0aXBDb250ZW50KCk7XG5cdFx0aW5zdGFuY2Uuc2hvdyhkZWxheSk7XG5cdH1cblxuXHQvKiogSGlkZXMgdGhlIHRvb2x0aXAgYWZ0ZXIgdGhlIGRlbGF5IGluIG1zLCBkZWZhdWx0cyB0byB0b29sdGlwLWRlbGF5LWhpZGUgb3IgMG1zIGlmIG5vIGlucHV0ICovXG5cdGhpZGUoZGVsYXk6IG51bWJlciA9IHRoaXMuaGlkZURlbGF5LCBleGl0QW5pbWF0aW9uRHVyYXRpb246IG51bWJlciA9IHRoaXMuZXhpdEFuaW1hdGlvbkR1cmF0aW9uKTogdm9pZCB7XG5cdFx0Y29uc3QgaW5zdGFuY2UgPSB0aGlzLl90b29sdGlwSW5zdGFuY2U7XG5cdFx0aWYgKGluc3RhbmNlKSB7XG5cdFx0XHRpZiAoaW5zdGFuY2UuaXNWaXNpYmxlKCkpIHtcblx0XHRcdFx0aW5zdGFuY2UuaGlkZShkZWxheSwgZXhpdEFuaW1hdGlvbkR1cmF0aW9uKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGluc3RhbmNlLl9jYW5jZWxQZW5kaW5nQW5pbWF0aW9ucygpO1xuXHRcdFx0XHR0aGlzLl9kZXRhY2goKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHR0b2dnbGUob3JpZ2luPzogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9KTogdm9pZCB7XG5cdFx0dGhpcy5faXNUb29sdGlwVmlzaWJsZSgpID8gdGhpcy5oaWRlKCkgOiB0aGlzLnNob3codW5kZWZpbmVkLCBvcmlnaW4pO1xuXHR9XG5cblx0X2lzVG9vbHRpcFZpc2libGUoKTogYm9vbGVhbiB7XG5cdFx0cmV0dXJuICEhdGhpcy5fdG9vbHRpcEluc3RhbmNlICYmIHRoaXMuX3Rvb2x0aXBJbnN0YW5jZS5pc1Zpc2libGUoKTtcblx0fVxuXG5cdHByaXZhdGUgX2NyZWF0ZU92ZXJsYXkob3JpZ2luPzogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9KTogT3ZlcmxheVJlZiB7XG5cdFx0aWYgKHRoaXMuX292ZXJsYXlSZWYpIHtcblx0XHRcdGNvbnN0IGV4aXN0aW5nU3RyYXRlZ3kgPSB0aGlzLl9vdmVybGF5UmVmLmdldENvbmZpZygpLnBvc2l0aW9uU3RyYXRlZ3kgYXMgRmxleGlibGVDb25uZWN0ZWRQb3NpdGlvblN0cmF0ZWd5O1xuXG5cdFx0XHRpZiAoKCF0aGlzLnBvc2l0aW9uQXRPcmlnaW4gfHwgIW9yaWdpbikgJiYgZXhpc3RpbmdTdHJhdGVneS5fb3JpZ2luIGluc3RhbmNlb2YgRWxlbWVudFJlZikge1xuXHRcdFx0XHRyZXR1cm4gdGhpcy5fb3ZlcmxheVJlZjtcblx0XHRcdH1cblxuXHRcdFx0dGhpcy5fZGV0YWNoKCk7XG5cdFx0fVxuXG5cdFx0Y29uc3Qgc2Nyb2xsYWJsZUFuY2VzdG9ycyA9IHRoaXMuX3Njcm9sbERpc3BhdGNoZXIuZ2V0QW5jZXN0b3JTY3JvbGxDb250YWluZXJzKHRoaXMuX2VsZW1lbnRSZWYpO1xuXG5cdFx0Ly8gQ3JlYXRlIGNvbm5lY3RlZCBwb3NpdGlvbiBzdHJhdGVneSB0aGF0IGxpc3RlbnMgZm9yIHNjcm9sbCBldmVudHMgdG8gcmVwb3NpdGlvbi5cblx0XHRjb25zdCBzdHJhdGVneSA9IHRoaXMuX292ZXJsYXlcblx0XHRcdC5wb3NpdGlvbigpXG5cdFx0XHQuZmxleGlibGVDb25uZWN0ZWRUbyh0aGlzLnBvc2l0aW9uQXRPcmlnaW4gPyBvcmlnaW4gfHwgdGhpcy5fZWxlbWVudFJlZiA6IHRoaXMuX2VsZW1lbnRSZWYpXG5cdFx0XHQud2l0aFRyYW5zZm9ybU9yaWdpbk9uKGAuJHt0aGlzLl9jc3NDbGFzc1ByZWZpeH0tdG9vbHRpcGApXG5cdFx0XHQud2l0aEZsZXhpYmxlRGltZW5zaW9ucyhmYWxzZSlcblx0XHRcdC53aXRoVmlld3BvcnRNYXJnaW4odGhpcy5fdmlld3BvcnRNYXJnaW4pXG5cdFx0XHQud2l0aFNjcm9sbGFibGVDb250YWluZXJzKHNjcm9sbGFibGVBbmNlc3RvcnMpO1xuXG5cdFx0c3RyYXRlZ3kucG9zaXRpb25DaGFuZ2VzLnBpcGUodGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3llZCkpLnN1YnNjcmliZSgoY2hhbmdlKSA9PiB7XG5cdFx0XHR0aGlzLl91cGRhdGVDdXJyZW50UG9zaXRpb25DbGFzcyhjaGFuZ2UuY29ubmVjdGlvblBhaXIpO1xuXG5cdFx0XHRpZiAodGhpcy5fdG9vbHRpcEluc3RhbmNlKSB7XG5cdFx0XHRcdGlmIChjaGFuZ2Uuc2Nyb2xsYWJsZVZpZXdQcm9wZXJ0aWVzLmlzT3ZlcmxheUNsaXBwZWQgJiYgdGhpcy5fdG9vbHRpcEluc3RhbmNlLmlzVmlzaWJsZSgpKSB7XG5cdFx0XHRcdFx0Ly8gQWZ0ZXIgcG9zaXRpb24gY2hhbmdlcyBvY2N1ciBhbmQgdGhlIG92ZXJsYXkgaXMgY2xpcHBlZCBieVxuXHRcdFx0XHRcdC8vIGEgcGFyZW50IHNjcm9sbGFibGUgdGhlbiBjbG9zZSB0aGUgdG9vbHRpcC5cblx0XHRcdFx0XHR0aGlzLl9uZ1pvbmUucnVuKCgpID0+IHRoaXMuaGlkZSgwKSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdHRoaXMuX292ZXJsYXlSZWYgPSB0aGlzLl9vdmVybGF5LmNyZWF0ZSh7XG5cdFx0XHRkaXJlY3Rpb246IHRoaXMuX2Rpcixcblx0XHRcdHBvc2l0aW9uU3RyYXRlZ3k6IHN0cmF0ZWd5LFxuXHRcdFx0cGFuZWxDbGFzczogYCR7dGhpcy5fY3NzQ2xhc3NQcmVmaXh9LSR7UEFORUxfQ0xBU1N9YCxcblx0XHRcdHNjcm9sbFN0cmF0ZWd5OiB0aGlzLl9zY3JvbGxTdHJhdGVneSgpLFxuXHRcdH0pO1xuXG5cdFx0dGhpcy5fdXBkYXRlUG9zaXRpb24odGhpcy5fb3ZlcmxheVJlZik7XG5cblx0XHR0aGlzLl9vdmVybGF5UmVmXG5cdFx0XHQuZGV0YWNobWVudHMoKVxuXHRcdFx0LnBpcGUodGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3llZCkpXG5cdFx0XHQuc3Vic2NyaWJlKCgpID0+IHRoaXMuX2RldGFjaCgpKTtcblxuXHRcdHRoaXMuX292ZXJsYXlSZWZcblx0XHRcdC5vdXRzaWRlUG9pbnRlckV2ZW50cygpXG5cdFx0XHQucGlwZSh0YWtlVW50aWwodGhpcy5fZGVzdHJveWVkKSlcblx0XHRcdC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5fdG9vbHRpcEluc3RhbmNlPy5faGFuZGxlQm9keUludGVyYWN0aW9uKCkpO1xuXG5cdFx0dGhpcy5fb3ZlcmxheVJlZlxuXHRcdFx0LmtleWRvd25FdmVudHMoKVxuXHRcdFx0LnBpcGUodGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3llZCkpXG5cdFx0XHQuc3Vic2NyaWJlKChldmVudCkgPT4ge1xuXHRcdFx0XHRpZiAodGhpcy5faXNUb29sdGlwVmlzaWJsZSgpICYmIGV2ZW50LmtleSA9PT0gJ0VzY2FwZScgJiYgIWhhc01vZGlmaWVyS2V5KGV2ZW50KSkge1xuXHRcdFx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdFx0ZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdFx0XHRcdFx0dGhpcy5fbmdab25lLnJ1bigoKSA9PiB0aGlzLmhpZGUoMCkpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblxuXHRcdGlmICh0aGlzLl9kZWZhdWx0T3B0aW9ucz8uZGlzYWJsZVRvb2x0aXBJbnRlcmFjdGl2aXR5KSB7XG5cdFx0XHR0aGlzLl9vdmVybGF5UmVmLmFkZFBhbmVsQ2xhc3MoYCR7dGhpcy5fY3NzQ2xhc3NQcmVmaXh9LXRvb2x0aXAtcGFuZWwtbm9uLWludGVyYWN0aXZlYCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMuX292ZXJsYXlSZWY7XG5cdH1cblxuXHRwcml2YXRlIF9kZXRhY2goKSB7XG5cdFx0aWYgKHRoaXMuX292ZXJsYXlSZWY/Lmhhc0F0dGFjaGVkKCkpIHtcblx0XHRcdHRoaXMuX292ZXJsYXlSZWYuZGV0YWNoKCk7XG5cdFx0fVxuXG5cdFx0dGhpcy5fdG9vbHRpcEluc3RhbmNlID0gbnVsbDtcblx0fVxuXG5cdHByaXZhdGUgX3VwZGF0ZVBvc2l0aW9uKG92ZXJsYXlSZWY6IE92ZXJsYXlSZWYpIHtcblx0XHRjb25zdCBwb3NpdGlvbiA9IG92ZXJsYXlSZWYuZ2V0Q29uZmlnKCkucG9zaXRpb25TdHJhdGVneSBhcyBGbGV4aWJsZUNvbm5lY3RlZFBvc2l0aW9uU3RyYXRlZ3k7XG5cdFx0Y29uc3Qgb3JpZ2luID0gdGhpcy5fZ2V0T3JpZ2luKCk7XG5cdFx0Y29uc3Qgb3ZlcmxheSA9IHRoaXMuX2dldE92ZXJsYXlQb3NpdGlvbigpO1xuXG5cdFx0cG9zaXRpb24ud2l0aFBvc2l0aW9ucyhbXG5cdFx0XHR0aGlzLl9hZGRPZmZzZXQoeyAuLi5vcmlnaW4ubWFpbiwgLi4ub3ZlcmxheS5tYWluIH0pLFxuXHRcdFx0dGhpcy5fYWRkT2Zmc2V0KHsgLi4ub3JpZ2luLmZhbGxiYWNrLCAuLi5vdmVybGF5LmZhbGxiYWNrIH0pLFxuXHRcdF0pO1xuXHR9XG5cblx0LyoqIEFkZHMgdGhlIGNvbmZpZ3VyZWQgb2Zmc2V0IHRvIGEgcG9zaXRpb24uIFVzZWQgYXMgYSBob29rIGZvciBjaGlsZCBjbGFzc2VzLiAqL1xuXHRwcm90ZWN0ZWQgX2FkZE9mZnNldChwb3NpdGlvbjogQ29ubmVjdGVkUG9zaXRpb24pOiBDb25uZWN0ZWRQb3NpdGlvbiB7XG5cdFx0Y29uc3Qgb2Zmc2V0ID0gVU5CT1VOREVEX0FOQ0hPUl9HQVA7XG5cdFx0Y29uc3QgaXNMdHIgPSAhdGhpcy5fZGlyIHx8IHRoaXMuX2Rpci52YWx1ZSA9PT0gJ2x0cic7XG5cblx0XHRpZiAocG9zaXRpb24ub3JpZ2luWSA9PT0gJ3RvcCcpIHtcblx0XHRcdHBvc2l0aW9uLm9mZnNldFkgPSAtb2Zmc2V0O1xuXHRcdH0gZWxzZSBpZiAocG9zaXRpb24ub3JpZ2luWSA9PT0gJ2JvdHRvbScpIHtcblx0XHRcdHBvc2l0aW9uLm9mZnNldFkgPSBvZmZzZXQ7XG5cdFx0fSBlbHNlIGlmIChwb3NpdGlvbi5vcmlnaW5YID09PSAnc3RhcnQnKSB7XG5cdFx0XHRwb3NpdGlvbi5vZmZzZXRYID0gaXNMdHIgPyAtb2Zmc2V0IDogb2Zmc2V0O1xuXHRcdH0gZWxzZSBpZiAocG9zaXRpb24ub3JpZ2luWCA9PT0gJ2VuZCcpIHtcblx0XHRcdHBvc2l0aW9uLm9mZnNldFggPSBpc0x0ciA/IG9mZnNldCA6IC1vZmZzZXQ7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHBvc2l0aW9uO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIG9yaWdpbiBwb3NpdGlvbiBhbmQgYSBmYWxsYmFjayBwb3NpdGlvbiBiYXNlZCBvbiB0aGUgdXNlcidzIHBvc2l0aW9uIHByZWZlcmVuY2UuXG5cdCAqIFRoZSBmYWxsYmFjayBwb3NpdGlvbiBpcyB0aGUgaW52ZXJzZSBvZiB0aGUgb3JpZ2luIChlLmcuIGAnYmVsb3cnIC0+ICdhYm92ZSdgKS5cblx0ICovXG5cdF9nZXRPcmlnaW4oKTogeyBtYWluOiBPcmlnaW5Db25uZWN0aW9uUG9zaXRpb247IGZhbGxiYWNrOiBPcmlnaW5Db25uZWN0aW9uUG9zaXRpb24gfSB7XG5cdFx0Y29uc3QgaXNMdHIgPSAhdGhpcy5fZGlyIHx8IHRoaXMuX2Rpci52YWx1ZSA9PT0gJ2x0cic7XG5cdFx0Y29uc3QgcG9zaXRpb24gPSB0aGlzLnBvc2l0aW9uO1xuXHRcdGxldCBvcmlnaW5Qb3NpdGlvbjogT3JpZ2luQ29ubmVjdGlvblBvc2l0aW9uO1xuXG5cdFx0aWYgKHBvc2l0aW9uID09PSAnYWJvdmUnIHx8IHBvc2l0aW9uID09PSAnYmVsb3cnKSB7XG5cdFx0XHRvcmlnaW5Qb3NpdGlvbiA9IHsgb3JpZ2luWDogJ2NlbnRlcicsIG9yaWdpblk6IHBvc2l0aW9uID09PSAnYWJvdmUnID8gJ3RvcCcgOiAnYm90dG9tJyB9O1xuXHRcdH0gZWxzZSBpZiAocG9zaXRpb24gPT09ICdiZWZvcmUnIHx8IChwb3NpdGlvbiA9PT0gJ2xlZnQnICYmIGlzTHRyKSB8fCAocG9zaXRpb24gPT09ICdyaWdodCcgJiYgIWlzTHRyKSkge1xuXHRcdFx0b3JpZ2luUG9zaXRpb24gPSB7IG9yaWdpblg6ICdzdGFydCcsIG9yaWdpblk6ICdjZW50ZXInIH07XG5cdFx0fSBlbHNlIGlmIChwb3NpdGlvbiA9PT0gJ2FmdGVyJyB8fCAocG9zaXRpb24gPT09ICdyaWdodCcgJiYgaXNMdHIpIHx8IChwb3NpdGlvbiA9PT0gJ2xlZnQnICYmICFpc0x0cikpIHtcblx0XHRcdG9yaWdpblBvc2l0aW9uID0geyBvcmlnaW5YOiAnZW5kJywgb3JpZ2luWTogJ2NlbnRlcicgfTtcblx0XHR9IGVsc2UgaWYgKHR5cGVvZiBpc0Rldk1vZGUoKSA9PT0gJ3VuZGVmaW5lZCcgfHwgaXNEZXZNb2RlKCkpIHtcblx0XHRcdHRocm93IGdldEJyblRvb2x0aXBJbnZhbGlkUG9zaXRpb25FcnJvcihwb3NpdGlvbik7XG5cdFx0fVxuXG5cdFx0Y29uc3QgeyB4LCB5IH0gPSB0aGlzLl9pbnZlcnRQb3NpdGlvbihvcmlnaW5Qb3NpdGlvbiEub3JpZ2luWCwgb3JpZ2luUG9zaXRpb24hLm9yaWdpblkpO1xuXG5cdFx0cmV0dXJuIHtcblx0XHRcdG1haW46IG9yaWdpblBvc2l0aW9uISxcblx0XHRcdGZhbGxiYWNrOiB7IG9yaWdpblg6IHgsIG9yaWdpblk6IHkgfSxcblx0XHR9O1xuXHR9XG5cblx0LyoqIFJldHVybnMgdGhlIG92ZXJsYXkgcG9zaXRpb24gYW5kIGEgZmFsbGJhY2sgcG9zaXRpb24gYmFzZWQgb24gdGhlIHVzZXIncyBwcmVmZXJlbmNlICovXG5cdF9nZXRPdmVybGF5UG9zaXRpb24oKTogeyBtYWluOiBPdmVybGF5Q29ubmVjdGlvblBvc2l0aW9uOyBmYWxsYmFjazogT3ZlcmxheUNvbm5lY3Rpb25Qb3NpdGlvbiB9IHtcblx0XHRjb25zdCBpc0x0ciA9ICF0aGlzLl9kaXIgfHwgdGhpcy5fZGlyLnZhbHVlID09PSAnbHRyJztcblx0XHRjb25zdCBwb3NpdGlvbiA9IHRoaXMucG9zaXRpb247XG5cdFx0bGV0IG92ZXJsYXlQb3NpdGlvbjogT3ZlcmxheUNvbm5lY3Rpb25Qb3NpdGlvbjtcblxuXHRcdGlmIChwb3NpdGlvbiA9PT0gJ2Fib3ZlJykge1xuXHRcdFx0b3ZlcmxheVBvc2l0aW9uID0geyBvdmVybGF5WDogJ2NlbnRlcicsIG92ZXJsYXlZOiAnYm90dG9tJyB9O1xuXHRcdH0gZWxzZSBpZiAocG9zaXRpb24gPT09ICdiZWxvdycpIHtcblx0XHRcdG92ZXJsYXlQb3NpdGlvbiA9IHsgb3ZlcmxheVg6ICdjZW50ZXInLCBvdmVybGF5WTogJ3RvcCcgfTtcblx0XHR9IGVsc2UgaWYgKHBvc2l0aW9uID09PSAnYmVmb3JlJyB8fCAocG9zaXRpb24gPT09ICdsZWZ0JyAmJiBpc0x0cikgfHwgKHBvc2l0aW9uID09PSAncmlnaHQnICYmICFpc0x0cikpIHtcblx0XHRcdG92ZXJsYXlQb3NpdGlvbiA9IHsgb3ZlcmxheVg6ICdlbmQnLCBvdmVybGF5WTogJ2NlbnRlcicgfTtcblx0XHR9IGVsc2UgaWYgKHBvc2l0aW9uID09PSAnYWZ0ZXInIHx8IChwb3NpdGlvbiA9PT0gJ3JpZ2h0JyAmJiBpc0x0cikgfHwgKHBvc2l0aW9uID09PSAnbGVmdCcgJiYgIWlzTHRyKSkge1xuXHRcdFx0b3ZlcmxheVBvc2l0aW9uID0geyBvdmVybGF5WDogJ3N0YXJ0Jywgb3ZlcmxheVk6ICdjZW50ZXInIH07XG5cdFx0fSBlbHNlIGlmICh0eXBlb2YgaXNEZXZNb2RlKCkgPT09ICd1bmRlZmluZWQnIHx8IGlzRGV2TW9kZSgpKSB7XG5cdFx0XHR0aHJvdyBnZXRCcm5Ub29sdGlwSW52YWxpZFBvc2l0aW9uRXJyb3IocG9zaXRpb24pO1xuXHRcdH1cblxuXHRcdGNvbnN0IHsgeCwgeSB9ID0gdGhpcy5faW52ZXJ0UG9zaXRpb24ob3ZlcmxheVBvc2l0aW9uIS5vdmVybGF5WCwgb3ZlcmxheVBvc2l0aW9uIS5vdmVybGF5WSk7XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0bWFpbjogb3ZlcmxheVBvc2l0aW9uISxcblx0XHRcdGZhbGxiYWNrOiB7IG92ZXJsYXlYOiB4LCBvdmVybGF5WTogeSB9LFxuXHRcdH07XG5cdH1cblxuXHQvKiogVXBkYXRlcyB0aGUgdG9vbHRpcCBtZXNzYWdlIGFuZCByZXBvc2l0aW9ucyB0aGUgb3ZlcmxheSBhY2NvcmRpbmcgdG8gdGhlIG5ldyBtZXNzYWdlIGxlbmd0aCAqL1xuXHRwcml2YXRlIF91cGRhdGVUb29sdGlwQ29udGVudCgpIHtcblx0XHQvLyBNdXN0IHdhaXQgZm9yIHRoZSB0ZW1wbGF0ZSB0byBiZSBwYWludGVkIHRvIHRoZSB0b29sdGlwIHNvIHRoYXQgdGhlIG92ZXJsYXkgY2FuIHByb3Blcmx5XG5cdFx0Ly8gY2FsY3VsYXRlIHRoZSBjb3JyZWN0IHBvc2l0aW9uaW5nIGJhc2VkIG9uIHRoZSBzaXplIG9mIHRoZSB0ZWstcGF0ZS5cblx0XHRpZiAodGhpcy5fdG9vbHRpcEluc3RhbmNlKSB7XG5cdFx0XHR0aGlzLl90b29sdGlwSW5zdGFuY2UuY29udGVudCA9IHRoaXMuY29udGVudDtcblx0XHRcdHRoaXMuX3Rvb2x0aXBJbnN0YW5jZS5fbWFya0ZvckNoZWNrKCk7XG5cblx0XHRcdHRoaXMuX25nWm9uZS5vbk1pY3JvdGFza0VtcHR5LnBpcGUodGFrZSgxKSwgdGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3llZCkpLnN1YnNjcmliZSgoKSA9PiB7XG5cdFx0XHRcdGlmICh0aGlzLl90b29sdGlwSW5zdGFuY2UpIHtcblx0XHRcdFx0XHR0aGlzLl9vdmVybGF5UmVmPy51cGRhdGVQb3NpdGlvbigpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9XG5cdH1cblxuXHQvKiogSW52ZXJ0cyBhbiBvdmVybGF5IHBvc2l0aW9uLiAqL1xuXHRwcml2YXRlIF9pbnZlcnRQb3NpdGlvbih4OiBIb3Jpem9udGFsQ29ubmVjdGlvblBvcywgeTogVmVydGljYWxDb25uZWN0aW9uUG9zKSB7XG5cdFx0aWYgKHRoaXMucG9zaXRpb24gPT09ICdhYm92ZScgfHwgdGhpcy5wb3NpdGlvbiA9PT0gJ2JlbG93Jykge1xuXHRcdFx0aWYgKHkgPT09ICd0b3AnKSB7XG5cdFx0XHRcdHkgPSAnYm90dG9tJztcblx0XHRcdH0gZWxzZSBpZiAoeSA9PT0gJ2JvdHRvbScpIHtcblx0XHRcdFx0eSA9ICd0b3AnO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAoeCA9PT0gJ2VuZCcpIHtcblx0XHRcdFx0eCA9ICdzdGFydCc7XG5cdFx0XHR9IGVsc2UgaWYgKHggPT09ICdzdGFydCcpIHtcblx0XHRcdFx0eCA9ICdlbmQnO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB7IHgsIHkgfTtcblx0fVxuXG5cdC8qKiBVcGRhdGVzIHRoZSBjbGFzcyBvbiB0aGUgb3ZlcmxheSBwYW5lbCBiYXNlZCBvbiB0aGUgY3VycmVudCBwb3NpdGlvbiBvZiB0aGUgdG9vbHRpcC4gKi9cblx0cHJpdmF0ZSBfdXBkYXRlQ3VycmVudFBvc2l0aW9uQ2xhc3MoY29ubmVjdGlvblBhaXI6IENvbm5lY3Rpb25Qb3NpdGlvblBhaXIpOiB2b2lkIHtcblx0XHRjb25zdCB7IG92ZXJsYXlZLCBvcmlnaW5YLCBvcmlnaW5ZIH0gPSBjb25uZWN0aW9uUGFpcjtcblx0XHRsZXQgbmV3UG9zaXRpb246IFRvb2x0aXBQb3NpdGlvbjtcblxuXHRcdC8vIElmIHRoZSBvdmVybGF5IGlzIGluIHRoZSBtaWRkbGUgYWxvbmcgdGhlIFkgYXhpcyxcblx0XHQvLyBpdCBtZWFucyB0aGF0IGl0J3MgZWl0aGVyIGJlZm9yZSBvciBhZnRlci5cblx0XHRpZiAob3ZlcmxheVkgPT09ICdjZW50ZXInKSB7XG5cdFx0XHQvLyBOb3RlIHRoYXQgc2luY2UgdGhpcyBpbmZvcm1hdGlvbiBpcyB1c2VkIGZvciBzdHlsaW5nLCB3ZSB3YW50IHRvXG5cdFx0XHQvLyByZXNvbHZlIGBzdGFydGAgYW5kIGBlbmRgIHRvIHRoZWlyIHJlYWwgdmFsdWVzLCBvdGhlcndpc2UgY29uc3VtZXJzXG5cdFx0XHQvLyB3b3VsZCBoYXZlIHRvIHJlbWVtYmVyIHRvIGRvIGl0IHRoZW1zZWx2ZXMgb24gZWFjaCBjb25zdW1wdGlvbi5cblx0XHRcdGlmICh0aGlzLl9kaXIgJiYgdGhpcy5fZGlyLnZhbHVlID09PSAncnRsJykge1xuXHRcdFx0XHRuZXdQb3NpdGlvbiA9IG9yaWdpblggPT09ICdlbmQnID8gJ2xlZnQnIDogJ3JpZ2h0Jztcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdG5ld1Bvc2l0aW9uID0gb3JpZ2luWCA9PT0gJ3N0YXJ0JyA/ICdsZWZ0JyA6ICdyaWdodCc7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdG5ld1Bvc2l0aW9uID0gb3ZlcmxheVkgPT09ICdib3R0b20nICYmIG9yaWdpblkgPT09ICd0b3AnID8gJ2Fib3ZlJyA6ICdiZWxvdyc7XG5cdFx0fVxuXG5cdFx0aWYgKG5ld1Bvc2l0aW9uICE9PSB0aGlzLl9jdXJyZW50UG9zaXRpb24pIHtcblx0XHRcdHRoaXMuX3Rvb2x0aXBJbnN0YW5jZT8uc2lkZS5zZXQobmV3UG9zaXRpb24pO1xuXHRcdFx0dGhpcy5fY3VycmVudFBvc2l0aW9uID0gbmV3UG9zaXRpb247XG5cdFx0fVxuXHR9XG5cblx0LyoqIEJpbmRzIHRoZSBwb2ludGVyIGV2ZW50cyB0byB0aGUgdG9vbHRpcCB0cmlnZ2VyLiAqL1xuXHRwcml2YXRlIF9zZXR1cFBvaW50ZXJFbnRlckV2ZW50c0lmTmVlZGVkKCkge1xuXHRcdC8vIE9wdGltaXphdGlvbjogRGVmZXIgaG9va2luZyB1cCBldmVudHMgaWYgdGhlcmUncyBubyBjb250ZW50IG9yIHRoZSB0b29sdGlwIGlzIGRpc2FibGVkLlxuXHRcdGlmICh0aGlzLl9kaXNhYmxlZCgpIHx8ICF0aGlzLmNvbnRlbnQgfHwgIXRoaXMuX3ZpZXdJbml0aWFsaXplZCB8fCB0aGlzLl9wYXNzaXZlTGlzdGVuZXJzLmxlbmd0aCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIFRoZSBtb3VzZSBldmVudHMgc2hvdWxkbid0IGJlIGJvdW5kIG9uIG1vYmlsZSBkZXZpY2VzLCBiZWNhdXNlIHRoZXkgY2FuIHByZXZlbnQgdGhlXG5cdFx0Ly8gZmlyc3QgdGFwIGZyb20gZmlyaW5nIGl0cyBjbGljayBldmVudCBvciBjYW4gY2F1c2UgdGhlIHRvb2x0aXAgdG8gb3BlbiBmb3IgY2xpY2tzLlxuXHRcdGlmICh0aGlzLl9wbGF0Zm9ybVN1cHBvcnRzTW91c2VFdmVudHMoKSkge1xuXHRcdFx0dGhpcy5fcGFzc2l2ZUxpc3RlbmVycy5wdXNoKFtcblx0XHRcdFx0J21vdXNlZW50ZXInLFxuXHRcdFx0XHQoZXZlbnQpID0+IHtcblx0XHRcdFx0XHR0aGlzLl9zZXR1cFBvaW50ZXJFeGl0RXZlbnRzSWZOZWVkZWQoKTtcblx0XHRcdFx0XHRsZXQgcG9pbnQgPSB1bmRlZmluZWQ7XG5cdFx0XHRcdFx0aWYgKChldmVudCBhcyBNb3VzZUV2ZW50KS54ICE9PSB1bmRlZmluZWQgJiYgKGV2ZW50IGFzIE1vdXNlRXZlbnQpLnkgIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRcdFx0cG9pbnQgPSBldmVudCBhcyBNb3VzZUV2ZW50O1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHR0aGlzLnNob3codW5kZWZpbmVkLCBwb2ludCk7XG5cdFx0XHRcdH0sXG5cdFx0XHRdKTtcblx0XHR9IGVsc2UgaWYgKHRoaXMudG91Y2hHZXN0dXJlcyAhPT0gJ29mZicpIHtcblx0XHRcdHRoaXMuX2Rpc2FibGVOYXRpdmVHZXN0dXJlc0lmTmVjZXNzYXJ5KCk7XG5cblx0XHRcdHRoaXMuX3Bhc3NpdmVMaXN0ZW5lcnMucHVzaChbXG5cdFx0XHRcdCd0b3VjaHN0YXJ0Jyxcblx0XHRcdFx0KGV2ZW50KSA9PiB7XG5cdFx0XHRcdFx0Y29uc3QgdG91Y2ggPSAoZXZlbnQgYXMgVG91Y2hFdmVudCkudGFyZ2V0VG91Y2hlcz8uWzBdO1xuXHRcdFx0XHRcdGNvbnN0IG9yaWdpbiA9IHRvdWNoID8geyB4OiB0b3VjaC5jbGllbnRYLCB5OiB0b3VjaC5jbGllbnRZIH0gOiB1bmRlZmluZWQ7XG5cdFx0XHRcdFx0Ly8gTm90ZSB0aGF0IGl0J3MgaW1wb3J0YW50IHRoYXQgd2UgZG9uJ3QgYHByZXZlbnREZWZhdWx0YCBoZXJlLFxuXHRcdFx0XHRcdC8vIGJlY2F1c2UgaXQgY2FuIHByZXZlbnQgY2xpY2sgZXZlbnRzIGZyb20gZmlyaW5nIG9uIHRoZSBlbGVtZW50LlxuXHRcdFx0XHRcdHRoaXMuX3NldHVwUG9pbnRlckV4aXRFdmVudHNJZk5lZWRlZCgpO1xuXHRcdFx0XHRcdGNsZWFyVGltZW91dCh0aGlzLl90b3VjaHN0YXJ0VGltZW91dCk7XG5cdFx0XHRcdFx0dGhpcy5fdG91Y2hzdGFydFRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHRoaXMuc2hvdyh1bmRlZmluZWQsIG9yaWdpbiksIExPTkdQUkVTU19ERUxBWSk7XG5cdFx0XHRcdH0sXG5cdFx0XHRdKTtcblx0XHR9XG5cblx0XHR0aGlzLl9hZGRMaXN0ZW5lcnModGhpcy5fcGFzc2l2ZUxpc3RlbmVycyk7XG5cdH1cblxuXHRwcml2YXRlIF9zZXR1cFBvaW50ZXJFeGl0RXZlbnRzSWZOZWVkZWQoKSB7XG5cdFx0aWYgKHRoaXMuX3BvaW50ZXJFeGl0RXZlbnRzSW5pdGlhbGl6ZWQpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0dGhpcy5fcG9pbnRlckV4aXRFdmVudHNJbml0aWFsaXplZCA9IHRydWU7XG5cblx0XHRjb25zdCBleGl0TGlzdGVuZXJzOiAocmVhZG9ubHkgW3N0cmluZywgRXZlbnRMaXN0ZW5lck9yRXZlbnRMaXN0ZW5lck9iamVjdF0pW10gPSBbXTtcblx0XHRpZiAodGhpcy5fcGxhdGZvcm1TdXBwb3J0c01vdXNlRXZlbnRzKCkpIHtcblx0XHRcdGV4aXRMaXN0ZW5lcnMucHVzaChcblx0XHRcdFx0W1xuXHRcdFx0XHRcdCdtb3VzZWxlYXZlJyxcblx0XHRcdFx0XHQoZXZlbnQpID0+IHtcblx0XHRcdFx0XHRcdGNvbnN0IG5ld1RhcmdldCA9IChldmVudCBhcyBNb3VzZUV2ZW50KS5yZWxhdGVkVGFyZ2V0IGFzIE5vZGUgfCBudWxsO1xuXHRcdFx0XHRcdFx0aWYgKCFuZXdUYXJnZXQgfHwgIXRoaXMuX292ZXJsYXlSZWY/Lm92ZXJsYXlFbGVtZW50LmNvbnRhaW5zKG5ld1RhcmdldCkpIHtcblx0XHRcdFx0XHRcdFx0dGhpcy5oaWRlKCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSxcblx0XHRcdFx0XSxcblx0XHRcdFx0Wyd3aGVlbCcsIChldmVudCkgPT4gdGhpcy5fd2hlZWxMaXN0ZW5lcihldmVudCBhcyBXaGVlbEV2ZW50KV0sXG5cdFx0XHQpO1xuXHRcdH0gZWxzZSBpZiAodGhpcy50b3VjaEdlc3R1cmVzICE9PSAnb2ZmJykge1xuXHRcdFx0dGhpcy5fZGlzYWJsZU5hdGl2ZUdlc3R1cmVzSWZOZWNlc3NhcnkoKTtcblx0XHRcdGNvbnN0IHRvdWNoZW5kTGlzdGVuZXIgPSAoKSA9PiB7XG5cdFx0XHRcdGNsZWFyVGltZW91dCh0aGlzLl90b3VjaHN0YXJ0VGltZW91dCk7XG5cdFx0XHRcdHRoaXMuaGlkZSh0aGlzLl9kZWZhdWx0T3B0aW9ucz8udG91Y2hlbmRIaWRlRGVsYXkpO1xuXHRcdFx0fTtcblxuXHRcdFx0ZXhpdExpc3RlbmVycy5wdXNoKFsndG91Y2hlbmQnLCB0b3VjaGVuZExpc3RlbmVyXSwgWyd0b3VjaGNhbmNlbCcsIHRvdWNoZW5kTGlzdGVuZXJdKTtcblx0XHR9XG5cblx0XHR0aGlzLl9hZGRMaXN0ZW5lcnMoZXhpdExpc3RlbmVycyk7XG5cdFx0dGhpcy5fcGFzc2l2ZUxpc3RlbmVycy5wdXNoKC4uLmV4aXRMaXN0ZW5lcnMpO1xuXHR9XG5cblx0cHJpdmF0ZSBfYWRkTGlzdGVuZXJzKGxpc3RlbmVyczogKHJlYWRvbmx5IFtzdHJpbmcsIEV2ZW50TGlzdGVuZXJPckV2ZW50TGlzdGVuZXJPYmplY3RdKVtdKSB7XG5cdFx0bGlzdGVuZXJzLmZvckVhY2goKFtldmVudCwgbGlzdGVuZXJdKSA9PiB7XG5cdFx0XHR0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgbGlzdGVuZXIsIHBhc3NpdmVMaXN0ZW5lck9wdGlvbnMpO1xuXHRcdH0pO1xuXHR9XG5cblx0cHJpdmF0ZSBfcGxhdGZvcm1TdXBwb3J0c01vdXNlRXZlbnRzKCkge1xuXHRcdHJldHVybiAhdGhpcy5fcGxhdGZvcm0uSU9TICYmICF0aGlzLl9wbGF0Zm9ybS5BTkRST0lEO1xuXHR9XG5cblx0LyoqIExpc3RlbmVyIGZvciB0aGUgYHdoZWVsYCBldmVudCBvbiB0aGUgZWxlbWVudC4gKi9cblx0cHJpdmF0ZSBfd2hlZWxMaXN0ZW5lcihldmVudDogV2hlZWxFdmVudCkge1xuXHRcdGlmICh0aGlzLl9pc1Rvb2x0aXBWaXNpYmxlKCkpIHtcblx0XHRcdGNvbnN0IGVsZW1lbnRVbmRlclBvaW50ZXIgPSB0aGlzLl9kb2N1bWVudC5lbGVtZW50RnJvbVBvaW50KGV2ZW50LmNsaWVudFgsIGV2ZW50LmNsaWVudFkpO1xuXHRcdFx0Y29uc3QgZWxlbWVudCA9IHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcblxuXHRcdFx0Ly8gT24gbm9uLXRvdWNoIGRldmljZXMgd2UgZGVwZW5kIG9uIHRoZSBgbW91c2VsZWF2ZWAgZXZlbnQgdG8gY2xvc2UgdGhlIHRvb2x0aXAsIGJ1dCBpdFxuXHRcdFx0Ly8gd29uJ3QgZmlyZSBpZiB0aGUgdXNlciBzY3JvbGxzIGF3YXkgdXNpbmcgdGhlIHdoZWVsIHdpdGhvdXQgbW92aW5nIHRoZWlyIGN1cnNvci4gV2Vcblx0XHRcdC8vIHdvcmsgYXJvdW5kIGl0IGJ5IGZpbmRpbmcgdGhlIGVsZW1lbnQgdW5kZXIgdGhlIHVzZXIncyBjdXJzb3IgYW5kIGNsb3NpbmcgdGhlIHRvb2x0aXBcblx0XHRcdC8vIGlmIGl0J3Mgbm90IHRoZSB0cmlnZ2VyLlxuXHRcdFx0aWYgKGVsZW1lbnRVbmRlclBvaW50ZXIgIT09IGVsZW1lbnQgJiYgIWVsZW1lbnQuY29udGFpbnMoZWxlbWVudFVuZGVyUG9pbnRlcikpIHtcblx0XHRcdFx0dGhpcy5oaWRlKCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqIERpc2FibGVzIHRoZSBuYXRpdmUgYnJvd3NlciBnZXN0dXJlcywgYmFzZWQgb24gaG93IHRoZSB0b29sdGlwIGhhcyBiZWVuIGNvbmZpZ3VyZWQuICovXG5cdHByaXZhdGUgX2Rpc2FibGVOYXRpdmVHZXN0dXJlc0lmTmVjZXNzYXJ5KCkge1xuXHRcdGNvbnN0IGdlc3R1cmVzID0gdGhpcy50b3VjaEdlc3R1cmVzO1xuXG5cdFx0aWYgKGdlc3R1cmVzICE9PSAnb2ZmJykge1xuXHRcdFx0Y29uc3QgZWxlbWVudCA9IHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcblx0XHRcdGNvbnN0IHN0eWxlID0gZWxlbWVudC5zdHlsZTtcblxuXHRcdFx0Ly8gSWYgZ2VzdHVyZXMgYXJlIHNldCB0byBgYXV0b2AsIHdlIGRvbid0IGRpc2FibGUgdGV4dCBzZWxlY3Rpb24gb24gaW5wdXRzIGFuZFxuXHRcdFx0Ly8gdGV4dGFyZWFzLCBiZWNhdXNlIGl0IHByZXZlbnRzIHRoZSB1c2VyIGZyb20gdHlwaW5nIGludG8gdGhlbSBvbiBpT1MgU2FmYXJpLlxuXHRcdFx0aWYgKGdlc3R1cmVzID09PSAnb24nIHx8IChlbGVtZW50Lm5vZGVOYW1lICE9PSAnSU5QVVQnICYmIGVsZW1lbnQubm9kZU5hbWUgIT09ICdURVhUQVJFQScpKSB7XG5cdFx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG5cdFx0XHRcdHN0eWxlLnVzZXJTZWxlY3QgPSAoc3R5bGUgYXMgYW55KS5tc1VzZXJTZWxlY3QgPSBzdHlsZS53ZWJraXRVc2VyU2VsZWN0ID0gKHN0eWxlIGFzIGFueSkuTW96VXNlclNlbGVjdCA9ICdub25lJztcblx0XHRcdH1cblxuXHRcdFx0Ly8gSWYgd2UgaGF2ZSBgYXV0b2AgZ2VzdHVyZXMgYW5kIHRoZSBlbGVtZW50IHVzZXMgbmF0aXZlIEhUTUwgZHJhZ2dpbmcsXG5cdFx0XHQvLyB3ZSBkb24ndCBzZXQgYC13ZWJraXQtdXNlci1kcmFnYCBiZWNhdXNlIGl0IHByZXZlbnRzIHRoZSBuYXRpdmUgYmVoYXZpb3IuXG5cdFx0XHRpZiAoZ2VzdHVyZXMgPT09ICdvbicgfHwgIWVsZW1lbnQuZHJhZ2dhYmxlKSB7XG5cdFx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG5cdFx0XHRcdChzdHlsZSBhcyBhbnkpLndlYmtpdFVzZXJEcmFnID0gJ25vbmUnO1xuXHRcdFx0fVxuXG5cdFx0XHRzdHlsZS50b3VjaEFjdGlvbiA9ICdub25lJztcblx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG5cdFx0XHQoc3R5bGUgYXMgYW55KS53ZWJraXRUYXBIaWdobGlnaHRDb2xvciA9ICd0cmFuc3BhcmVudCc7XG5cdFx0fVxuXHR9XG59XG4iXX0=
|