{"ast":null,"code":"import { takeUntil, take } from 'rxjs/operators';\nimport { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';\nimport { ESCAPE, hasModifierKey } from '@angular/cdk/keycodes';\nimport * as i0 from '@angular/core';\nimport { InjectionToken, inject, ElementRef, Directive, Inject, Optional, Input, ANIMATION_MODULE_TYPE, Component, ViewEncapsulation, ChangeDetectionStrategy, ViewChild, NgModule } from '@angular/core';\nimport { DOCUMENT, NgClass, CommonModule } from '@angular/common';\nimport * as i2 from '@angular/cdk/platform';\nimport { normalizePassiveListenerOptions } from '@angular/cdk/platform';\nimport * as i3 from '@angular/cdk/a11y';\nimport { A11yModule } from '@angular/cdk/a11y';\nimport * as i4 from '@angular/cdk/bidi';\nimport * as i1 from '@angular/cdk/overlay';\nimport { Overlay, OverlayModule } from '@angular/cdk/overlay';\nimport { ComponentPortal } from '@angular/cdk/portal';\nimport { Subject } from 'rxjs';\nimport { trigger, state, style, transition, animate } from '@angular/animations';\nimport { CdkScrollableModule } from '@angular/cdk/scrolling';\nimport { MatCommonModule } from '@angular/material/core';\n\n/** Time in ms to throttle repositioning after scroll events. */\nconst _c0 = [\"tooltip\"];\nconst SCROLL_THROTTLE_MS = 20;\n/**\n * Creates an error to be thrown if the user supplied an invalid tooltip position.\n * @docs-private\n */\nfunction getMatTooltipInvalidPositionError(position) {\n  return Error(`Tooltip position \"${position}\" is invalid.`);\n}\n/** Injection token that determines the scroll handling while a tooltip is visible. */\nconst MAT_TOOLTIP_SCROLL_STRATEGY = /*#__PURE__*/new InjectionToken('mat-tooltip-scroll-strategy', {\n  providedIn: 'root',\n  factory: () => {\n    const overlay = inject(Overlay);\n    return () => overlay.scrollStrategies.reposition({\n      scrollThrottle: SCROLL_THROTTLE_MS\n    });\n  }\n});\n/** @docs-private */\nfunction MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY(overlay) {\n  return () => overlay.scrollStrategies.reposition({\n    scrollThrottle: SCROLL_THROTTLE_MS\n  });\n}\n/** @docs-private */\nconst MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY_PROVIDER = {\n  provide: MAT_TOOLTIP_SCROLL_STRATEGY,\n  deps: [Overlay],\n  useFactory: MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY\n};\n/** @docs-private */\nfunction MAT_TOOLTIP_DEFAULT_OPTIONS_FACTORY() {\n  return {\n    showDelay: 0,\n    hideDelay: 0,\n    touchendHideDelay: 1500\n  };\n}\n/** Injection token to be used to override the default options for `matTooltip`. */\nconst MAT_TOOLTIP_DEFAULT_OPTIONS = /*#__PURE__*/new InjectionToken('mat-tooltip-default-options', {\n  providedIn: 'root',\n  factory: MAT_TOOLTIP_DEFAULT_OPTIONS_FACTORY\n});\n/**\n * CSS class that will be attached to the overlay panel.\n * @deprecated\n * @breaking-change 13.0.0 remove this variable\n */\nconst TOOLTIP_PANEL_CLASS = 'mat-mdc-tooltip-panel';\nconst PANEL_CLASS = 'tooltip-panel';\n/** Options used to bind passive event listeners. */\nconst passiveListenerOptions = /*#__PURE__*/normalizePassiveListenerOptions({\n  passive: true\n});\n// These constants were taken from MDC's `numbers` object. We can't import them from MDC,\n// because they have some top-level references to `window` which break during SSR.\nconst MIN_VIEWPORT_TOOLTIP_THRESHOLD = 8;\nconst UNBOUNDED_ANCHOR_GAP = 8;\nconst MIN_HEIGHT = 24;\nconst MAX_WIDTH = 200;\n/**\n * Directive that attaches a material design tooltip to the host element. Animates the showing and\n * hiding of a tooltip provided position (defaults to below the element).\n *\n * https://material.io/design/components/tooltips.html\n */\nlet MatTooltip = /*#__PURE__*/(() => {\n  class MatTooltip {\n    /** Allows the user to define the position of the tooltip relative to the parent element */\n    get position() {\n      return this._position;\n    }\n    set position(value) {\n      if (value !== this._position) {\n        this._position = value;\n        if (this._overlayRef) {\n          this._updatePosition(this._overlayRef);\n          this._tooltipInstance?.show(0);\n          this._overlayRef.updatePosition();\n        }\n      }\n    }\n    /**\n     * Whether tooltip should be relative to the click or touch origin\n     * instead of outside the element bounding box.\n     */\n    get positionAtOrigin() {\n      return this._positionAtOrigin;\n    }\n    set positionAtOrigin(value) {\n      this._positionAtOrigin = coerceBooleanProperty(value);\n      this._detach();\n      this._overlayRef = null;\n    }\n    /** Disables the display of the tooltip. */\n    get disabled() {\n      return this._disabled;\n    }\n    set disabled(value) {\n      this._disabled = coerceBooleanProperty(value);\n      // If tooltip is disabled, hide immediately.\n      if (this._disabled) {\n        this.hide(0);\n      } else {\n        this._setupPointerEnterEventsIfNeeded();\n      }\n    }\n    /** The default delay in ms before showing the tooltip after show is called */\n    get showDelay() {\n      return this._showDelay;\n    }\n    set showDelay(value) {\n      this._showDelay = coerceNumberProperty(value);\n    }\n    /** The default delay in ms before hiding the tooltip after hide is called */\n    get hideDelay() {\n      return this._hideDelay;\n    }\n    set hideDelay(value) {\n      this._hideDelay = coerceNumberProperty(value);\n      if (this._tooltipInstance) {\n        this._tooltipInstance._mouseLeaveHideDelay = this._hideDelay;\n      }\n    }\n    /** The message to be displayed in the tooltip */\n    get message() {\n      return this._message;\n    }\n    set message(value) {\n      this._ariaDescriber.removeDescription(this._elementRef.nativeElement, this._message, 'tooltip');\n      // If the message is not a string (e.g. number), convert it to a string and trim it.\n      // Must convert with `String(value)`, not `${value}`, otherwise Closure Compiler optimises\n      // away the string-conversion: https://github.com/angular/components/issues/20684\n      this._message = value != null ? String(value).trim() : '';\n      if (!this._message && this._isTooltipVisible()) {\n        this.hide(0);\n      } else {\n        this._setupPointerEnterEventsIfNeeded();\n        this._updateTooltipMessage();\n        this._ngZone.runOutsideAngular(() => {\n          // The `AriaDescriber` has some functionality that avoids adding a description if it's the\n          // same as the `aria-label` of an element, however we can't know whether the tooltip trigger\n          // has a data-bound `aria-label` or when it'll be set for the first time. We can avoid the\n          // issue by deferring the description by a tick so Angular has time to set the `aria-label`.\n          Promise.resolve().then(() => {\n            this._ariaDescriber.describe(this._elementRef.nativeElement, this.message, 'tooltip');\n          });\n        });\n      }\n    }\n    /** Classes to be passed to the tooltip. Supports the same syntax as `ngClass`. */\n    get tooltipClass() {\n      return this._tooltipClass;\n    }\n    set tooltipClass(value) {\n      this._tooltipClass = value;\n      if (this._tooltipInstance) {\n        this._setTooltipClass(this._tooltipClass);\n      }\n    }\n    constructor(_overlay, _elementRef, _scrollDispatcher, _viewContainerRef, _ngZone, _platform, _ariaDescriber, _focusMonitor, scrollStrategy, _dir, _defaultOptions, _document) {\n      this._overlay = _overlay;\n      this._elementRef = _elementRef;\n      this._scrollDispatcher = _scrollDispatcher;\n      this._viewContainerRef = _viewContainerRef;\n      this._ngZone = _ngZone;\n      this._platform = _platform;\n      this._ariaDescriber = _ariaDescriber;\n      this._focusMonitor = _focusMonitor;\n      this._dir = _dir;\n      this._defaultOptions = _defaultOptions;\n      this._position = 'below';\n      this._positionAtOrigin = false;\n      this._disabled = false;\n      this._viewInitialized = false;\n      this._pointerExitEventsInitialized = false;\n      this._tooltipComponent = TooltipComponent;\n      this._viewportMargin = 8;\n      this._cssClassPrefix = 'mat-mdc';\n      /**\n       * How touch gestures should be handled by the tooltip. On touch devices the tooltip directive\n       * uses a long press gesture to show and hide, however it can conflict with the native browser\n       * gestures. To work around the conflict, Angular Material disables native gestures on the\n       * trigger, but that might not be desirable on particular elements (e.g. inputs and draggable\n       * elements). The different values for this option configure the touch event handling as follows:\n       * - `auto` - Enables touch gestures for all elements, but tries to avoid conflicts with native\n       *   browser gestures on particular elements. In particular, it allows text selection on inputs\n       *   and textareas, and preserves the native browser dragging on elements marked as `draggable`.\n       * - `on` - Enables touch gestures for all elements and disables native\n       *   browser gestures with no exceptions.\n       * - `off` - Disables touch gestures. Note that this will prevent the tooltip from\n       *   showing on touch devices.\n       */\n      this.touchGestures = 'auto';\n      this._message = '';\n      /** Manually-bound passive event listeners. */\n      this._passiveListeners = [];\n      /** Emits when the component is destroyed. */\n      this._destroyed = new Subject();\n      this._scrollStrategy = scrollStrategy;\n      this._document = _document;\n      if (_defaultOptions) {\n        this._showDelay = _defaultOptions.showDelay;\n        this._hideDelay = _defaultOptions.hideDelay;\n        if (_defaultOptions.position) {\n          this.position = _defaultOptions.position;\n        }\n        if (_defaultOptions.positionAtOrigin) {\n          this.positionAtOrigin = _defaultOptions.positionAtOrigin;\n        }\n        if (_defaultOptions.touchGestures) {\n          this.touchGestures = _defaultOptions.touchGestures;\n        }\n      }\n      _dir.change.pipe(takeUntil(this._destroyed)).subscribe(() => {\n        if (this._overlayRef) {\n          this._updatePosition(this._overlayRef);\n        }\n      });\n      this._viewportMargin = MIN_VIEWPORT_TOOLTIP_THRESHOLD;\n    }\n    ngAfterViewInit() {\n      // This needs to happen after view init so the initial values for all inputs have been set.\n      this._viewInitialized = true;\n      this._setupPointerEnterEventsIfNeeded();\n      this._focusMonitor.monitor(this._elementRef).pipe(takeUntil(this._destroyed)).subscribe(origin => {\n        // Note that the focus monitor runs outside the Angular zone.\n        if (!origin) {\n          this._ngZone.run(() => this.hide(0));\n        } else if (origin === 'keyboard') {\n          this._ngZone.run(() => this.show());\n        }\n      });\n    }\n    /**\n     * Dispose the tooltip when destroyed.\n     */\n    ngOnDestroy() {\n      const nativeElement = this._elementRef.nativeElement;\n      clearTimeout(this._touchstartTimeout);\n      if (this._overlayRef) {\n        this._overlayRef.dispose();\n        this._tooltipInstance = null;\n      }\n      // Clean up the event listeners set in the constructor\n      this._passiveListeners.forEach(([event, listener]) => {\n        nativeElement.removeEventListener(event, listener, passiveListenerOptions);\n      });\n      this._passiveListeners.length = 0;\n      this._destroyed.next();\n      this._destroyed.complete();\n      this._ariaDescriber.removeDescription(nativeElement, this.message, 'tooltip');\n      this._focusMonitor.stopMonitoring(nativeElement);\n    }\n    /** Shows the tooltip after the delay in ms, defaults to tooltip-delay-show or 0ms if no input */\n    show(delay = this.showDelay, origin) {\n      if (this.disabled || !this.message || this._isTooltipVisible()) {\n        this._tooltipInstance?._cancelPendingAnimations();\n        return;\n      }\n      const overlayRef = this._createOverlay(origin);\n      this._detach();\n      this._portal = this._portal || new ComponentPortal(this._tooltipComponent, this._viewContainerRef);\n      const instance = this._tooltipInstance = overlayRef.attach(this._portal).instance;\n      instance._triggerElement = this._elementRef.nativeElement;\n      instance._mouseLeaveHideDelay = this._hideDelay;\n      instance.afterHidden().pipe(takeUntil(this._destroyed)).subscribe(() => this._detach());\n      this._setTooltipClass(this._tooltipClass);\n      this._updateTooltipMessage();\n      instance.show(delay);\n    }\n    /** Hides the tooltip after the delay in ms, defaults to tooltip-delay-hide or 0ms if no input */\n    hide(delay = this.hideDelay) {\n      const instance = this._tooltipInstance;\n      if (instance) {\n        if (instance.isVisible()) {\n          instance.hide(delay);\n        } else {\n          instance._cancelPendingAnimations();\n          this._detach();\n        }\n      }\n    }\n    /** Shows/hides the tooltip */\n    toggle(origin) {\n      this._isTooltipVisible() ? this.hide() : this.show(undefined, origin);\n    }\n    /** Returns true if the tooltip is currently visible to the user */\n    _isTooltipVisible() {\n      return !!this._tooltipInstance && this._tooltipInstance.isVisible();\n    }\n    /** Create the overlay config and position strategy */\n    _createOverlay(origin) {\n      if (this._overlayRef) {\n        const existingStrategy = this._overlayRef.getConfig().positionStrategy;\n        if ((!this.positionAtOrigin || !origin) && existingStrategy._origin instanceof ElementRef) {\n          return this._overlayRef;\n        }\n        this._detach();\n      }\n      const scrollableAncestors = this._scrollDispatcher.getAncestorScrollContainers(this._elementRef);\n      // Create connected position strategy that listens for scroll events to reposition.\n      const strategy = this._overlay.position().flexibleConnectedTo(this.positionAtOrigin ? origin || this._elementRef : this._elementRef).withTransformOriginOn(`.${this._cssClassPrefix}-tooltip`).withFlexibleDimensions(false).withViewportMargin(this._viewportMargin).withScrollableContainers(scrollableAncestors);\n      strategy.positionChanges.pipe(takeUntil(this._destroyed)).subscribe(change => {\n        this._updateCurrentPositionClass(change.connectionPair);\n        if (this._tooltipInstance) {\n          if (change.scrollableViewProperties.isOverlayClipped && this._tooltipInstance.isVisible()) {\n            // After position changes occur and the overlay is clipped by\n            // a parent scrollable then close the tooltip.\n            this._ngZone.run(() => this.hide(0));\n          }\n        }\n      });\n      this._overlayRef = this._overlay.create({\n        direction: this._dir,\n        positionStrategy: strategy,\n        panelClass: `${this._cssClassPrefix}-${PANEL_CLASS}`,\n        scrollStrategy: this._scrollStrategy()\n      });\n      this._updatePosition(this._overlayRef);\n      this._overlayRef.detachments().pipe(takeUntil(this._destroyed)).subscribe(() => this._detach());\n      this._overlayRef.outsidePointerEvents().pipe(takeUntil(this._destroyed)).subscribe(() => this._tooltipInstance?._handleBodyInteraction());\n      this._overlayRef.keydownEvents().pipe(takeUntil(this._destroyed)).subscribe(event => {\n        if (this._isTooltipVisible() && event.keyCode === ESCAPE && !hasModifierKey(event)) {\n          event.preventDefault();\n          event.stopPropagation();\n          this._ngZone.run(() => this.hide(0));\n        }\n      });\n      if (this._defaultOptions?.disableTooltipInteractivity) {\n        this._overlayRef.addPanelClass(`${this._cssClassPrefix}-tooltip-panel-non-interactive`);\n      }\n      return this._overlayRef;\n    }\n    /** Detaches the currently-attached tooltip. */\n    _detach() {\n      if (this._overlayRef && this._overlayRef.hasAttached()) {\n        this._overlayRef.detach();\n      }\n      this._tooltipInstance = null;\n    }\n    /** Updates the position of the current tooltip. */\n    _updatePosition(overlayRef) {\n      const position = overlayRef.getConfig().positionStrategy;\n      const origin = this._getOrigin();\n      const overlay = this._getOverlayPosition();\n      position.withPositions([this._addOffset({\n        ...origin.main,\n        ...overlay.main\n      }), this._addOffset({\n        ...origin.fallback,\n        ...overlay.fallback\n      })]);\n    }\n    /** Adds the configured offset to a position. Used as a hook for child classes. */\n    _addOffset(position) {\n      const offset = UNBOUNDED_ANCHOR_GAP;\n      const isLtr = !this._dir || this._dir.value == 'ltr';\n      if (position.originY === 'top') {\n        position.offsetY = -offset;\n      } else if (position.originY === 'bottom') {\n        position.offsetY = offset;\n      } else if (position.originX === 'start') {\n        position.offsetX = isLtr ? -offset : offset;\n      } else if (position.originX === 'end') {\n        position.offsetX = isLtr ? offset : -offset;\n      }\n      return position;\n    }\n    /**\n     * Returns the origin position and a fallback position based on the user's position preference.\n     * The fallback position is the inverse of the origin (e.g. `'below' -> 'above'`).\n     */\n    _getOrigin() {\n      const isLtr = !this._dir || this._dir.value == 'ltr';\n      const position = this.position;\n      let originPosition;\n      if (position == 'above' || position == 'below') {\n        originPosition = {\n          originX: 'center',\n          originY: position == 'above' ? 'top' : 'bottom'\n        };\n      } else if (position == 'before' || position == 'left' && isLtr || position == 'right' && !isLtr) {\n        originPosition = {\n          originX: 'start',\n          originY: 'center'\n        };\n      } else if (position == 'after' || position == 'right' && isLtr || position == 'left' && !isLtr) {\n        originPosition = {\n          originX: 'end',\n          originY: 'center'\n        };\n      } else if (typeof ngDevMode === 'undefined' || ngDevMode) {\n        throw getMatTooltipInvalidPositionError(position);\n      }\n      const {\n        x,\n        y\n      } = this._invertPosition(originPosition.originX, originPosition.originY);\n      return {\n        main: originPosition,\n        fallback: {\n          originX: x,\n          originY: y\n        }\n      };\n    }\n    /** Returns the overlay position and a fallback position based on the user's preference */\n    _getOverlayPosition() {\n      const isLtr = !this._dir || this._dir.value == 'ltr';\n      const position = this.position;\n      let overlayPosition;\n      if (position == 'above') {\n        overlayPosition = {\n          overlayX: 'center',\n          overlayY: 'bottom'\n        };\n      } else if (position == 'below') {\n        overlayPosition = {\n          overlayX: 'center',\n          overlayY: 'top'\n        };\n      } else if (position == 'before' || position == 'left' && isLtr || position == 'right' && !isLtr) {\n        overlayPosition = {\n          overlayX: 'end',\n          overlayY: 'center'\n        };\n      } else if (position == 'after' || position == 'right' && isLtr || position == 'left' && !isLtr) {\n        overlayPosition = {\n          overlayX: 'start',\n          overlayY: 'center'\n        };\n      } else if (typeof ngDevMode === 'undefined' || ngDevMode) {\n        throw getMatTooltipInvalidPositionError(position);\n      }\n      const {\n        x,\n        y\n      } = this._invertPosition(overlayPosition.overlayX, overlayPosition.overlayY);\n      return {\n        main: overlayPosition,\n        fallback: {\n          overlayX: x,\n          overlayY: y\n        }\n      };\n    }\n    /** Updates the tooltip message and repositions the overlay according to the new message length */\n    _updateTooltipMessage() {\n      // Must wait for the message to be painted to the tooltip so that the overlay can properly\n      // calculate the correct positioning based on the size of the text.\n      if (this._tooltipInstance) {\n        this._tooltipInstance.message = this.message;\n        this._tooltipInstance._markForCheck();\n        this._ngZone.onMicrotaskEmpty.pipe(take(1), takeUntil(this._destroyed)).subscribe(() => {\n          if (this._tooltipInstance) {\n            this._overlayRef.updatePosition();\n          }\n        });\n      }\n    }\n    /** Updates the tooltip class */\n    _setTooltipClass(tooltipClass) {\n      if (this._tooltipInstance) {\n        this._tooltipInstance.tooltipClass = tooltipClass;\n        this._tooltipInstance._markForCheck();\n      }\n    }\n    /** Inverts an overlay position. */\n    _invertPosition(x, y) {\n      if (this.position === 'above' || this.position === 'below') {\n        if (y === 'top') {\n          y = 'bottom';\n        } else if (y === 'bottom') {\n          y = 'top';\n        }\n      } else {\n        if (x === 'end') {\n          x = 'start';\n        } else if (x === 'start') {\n          x = 'end';\n        }\n      }\n      return {\n        x,\n        y\n      };\n    }\n    /** Updates the class on the overlay panel based on the current position of the tooltip. */\n    _updateCurrentPositionClass(connectionPair) {\n      const {\n        overlayY,\n        originX,\n        originY\n      } = connectionPair;\n      let newPosition;\n      // If the overlay is in the middle along the Y axis,\n      // it means that it's either before or after.\n      if (overlayY === 'center') {\n        // Note that since this information is used for styling, we want to\n        // resolve `start` and `end` to their real values, otherwise consumers\n        // would have to remember to do it themselves on each consumption.\n        if (this._dir && this._dir.value === 'rtl') {\n          newPosition = originX === 'end' ? 'left' : 'right';\n        } else {\n          newPosition = originX === 'start' ? 'left' : 'right';\n        }\n      } else {\n        newPosition = overlayY === 'bottom' && originY === 'top' ? 'above' : 'below';\n      }\n      if (newPosition !== this._currentPosition) {\n        const overlayRef = this._overlayRef;\n        if (overlayRef) {\n          const classPrefix = `${this._cssClassPrefix}-${PANEL_CLASS}-`;\n          overlayRef.removePanelClass(classPrefix + this._currentPosition);\n          overlayRef.addPanelClass(classPrefix + newPosition);\n        }\n        this._currentPosition = newPosition;\n      }\n    }\n    /** Binds the pointer events to the tooltip trigger. */\n    _setupPointerEnterEventsIfNeeded() {\n      // Optimization: Defer hooking up events if there's no message or the tooltip is disabled.\n      if (this._disabled || !this.message || !this._viewInitialized || this._passiveListeners.length) {\n        return;\n      }\n      // The mouse events shouldn't be bound on mobile devices, because they can prevent the\n      // first tap from firing its click event or can cause the tooltip to open for clicks.\n      if (this._platformSupportsMouseEvents()) {\n        this._passiveListeners.push(['mouseenter', event => {\n          this._setupPointerExitEventsIfNeeded();\n          let point = undefined;\n          if (event.x !== undefined && event.y !== undefined) {\n            point = event;\n          }\n          this.show(undefined, point);\n        }]);\n      } else if (this.touchGestures !== 'off') {\n        this._disableNativeGesturesIfNecessary();\n        this._passiveListeners.push(['touchstart', event => {\n          const touch = event.targetTouches?.[0];\n          const origin = touch ? {\n            x: touch.clientX,\n            y: touch.clientY\n          } : undefined;\n          // Note that it's important that we don't `preventDefault` here,\n          // because it can prevent click events from firing on the element.\n          this._setupPointerExitEventsIfNeeded();\n          clearTimeout(this._touchstartTimeout);\n          const DEFAULT_LONGPRESS_DELAY = 500;\n          this._touchstartTimeout = setTimeout(() => this.show(undefined, origin), this._defaultOptions.touchLongPressShowDelay ?? DEFAULT_LONGPRESS_DELAY);\n        }]);\n      }\n      this._addListeners(this._passiveListeners);\n    }\n    _setupPointerExitEventsIfNeeded() {\n      if (this._pointerExitEventsInitialized) {\n        return;\n      }\n      this._pointerExitEventsInitialized = true;\n      const exitListeners = [];\n      if (this._platformSupportsMouseEvents()) {\n        exitListeners.push(['mouseleave', event => {\n          const newTarget = event.relatedTarget;\n          if (!newTarget || !this._overlayRef?.overlayElement.contains(newTarget)) {\n            this.hide();\n          }\n        }], ['wheel', event => this._wheelListener(event)]);\n      } else if (this.touchGestures !== 'off') {\n        this._disableNativeGesturesIfNecessary();\n        const touchendListener = () => {\n          clearTimeout(this._touchstartTimeout);\n          this.hide(this._defaultOptions.touchendHideDelay);\n        };\n        exitListeners.push(['touchend', touchendListener], ['touchcancel', touchendListener]);\n      }\n      this._addListeners(exitListeners);\n      this._passiveListeners.push(...exitListeners);\n    }\n    _addListeners(listeners) {\n      listeners.forEach(([event, listener]) => {\n        this._elementRef.nativeElement.addEventListener(event, listener, passiveListenerOptions);\n      });\n    }\n    _platformSupportsMouseEvents() {\n      return !this._platform.IOS && !this._platform.ANDROID;\n    }\n    /** Listener for the `wheel` event on the element. */\n    _wheelListener(event) {\n      if (this._isTooltipVisible()) {\n        const elementUnderPointer = this._document.elementFromPoint(event.clientX, event.clientY);\n        const element = this._elementRef.nativeElement;\n        // On non-touch devices we depend on the `mouseleave` event to close the tooltip, but it\n        // won't fire if the user scrolls away using the wheel without moving their cursor. We\n        // work around it by finding the element under the user's cursor and closing the tooltip\n        // if it's not the trigger.\n        if (elementUnderPointer !== element && !element.contains(elementUnderPointer)) {\n          this.hide();\n        }\n      }\n    }\n    /** Disables the native browser gestures, based on how the tooltip has been configured. */\n    _disableNativeGesturesIfNecessary() {\n      const gestures = this.touchGestures;\n      if (gestures !== 'off') {\n        const element = this._elementRef.nativeElement;\n        const style = element.style;\n        // If gestures are set to `auto`, we don't disable text selection on inputs and\n        // textareas, because it prevents the user from typing into them on iOS Safari.\n        if (gestures === 'on' || element.nodeName !== 'INPUT' && element.nodeName !== 'TEXTAREA') {\n          style.userSelect = style.msUserSelect = style.webkitUserSelect = style.MozUserSelect = 'none';\n        }\n        // If we have `auto` gestures and the element uses native HTML dragging,\n        // we don't set `-webkit-user-drag` because it prevents the native behavior.\n        if (gestures === 'on' || !element.draggable) {\n          style.webkitUserDrag = 'none';\n        }\n        style.touchAction = 'none';\n        style.webkitTapHighlightColor = 'transparent';\n      }\n    }\n    static #_ = this.ɵfac = function MatTooltip_Factory(t) {\n      return new (t || MatTooltip)(i0.ɵɵdirectiveInject(i1.Overlay), i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i1.ScrollDispatcher), i0.ɵɵdirectiveInject(i0.ViewContainerRef), i0.ɵɵdirectiveInject(i0.NgZone), i0.ɵɵdirectiveInject(i2.Platform), i0.ɵɵdirectiveInject(i3.AriaDescriber), i0.ɵɵdirectiveInject(i3.FocusMonitor), i0.ɵɵdirectiveInject(MAT_TOOLTIP_SCROLL_STRATEGY), i0.ɵɵdirectiveInject(i4.Directionality), i0.ɵɵdirectiveInject(MAT_TOOLTIP_DEFAULT_OPTIONS, 8), i0.ɵɵdirectiveInject(DOCUMENT));\n    };\n    static #_2 = this.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n      type: MatTooltip,\n      selectors: [[\"\", \"matTooltip\", \"\"]],\n      hostAttrs: [1, \"mat-mdc-tooltip-trigger\"],\n      hostVars: 2,\n      hostBindings: function MatTooltip_HostBindings(rf, ctx) {\n        if (rf & 2) {\n          i0.ɵɵclassProp(\"mat-mdc-tooltip-disabled\", ctx.disabled);\n        }\n      },\n      inputs: {\n        position: [i0.ɵɵInputFlags.None, \"matTooltipPosition\", \"position\"],\n        positionAtOrigin: [i0.ɵɵInputFlags.None, \"matTooltipPositionAtOrigin\", \"positionAtOrigin\"],\n        disabled: [i0.ɵɵInputFlags.None, \"matTooltipDisabled\", \"disabled\"],\n        showDelay: [i0.ɵɵInputFlags.None, \"matTooltipShowDelay\", \"showDelay\"],\n        hideDelay: [i0.ɵɵInputFlags.None, \"matTooltipHideDelay\", \"hideDelay\"],\n        touchGestures: [i0.ɵɵInputFlags.None, \"matTooltipTouchGestures\", \"touchGestures\"],\n        message: [i0.ɵɵInputFlags.None, \"matTooltip\", \"message\"],\n        tooltipClass: [i0.ɵɵInputFlags.None, \"matTooltipClass\", \"tooltipClass\"]\n      },\n      exportAs: [\"matTooltip\"],\n      standalone: true\n    });\n  }\n  return MatTooltip;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * Internal component that wraps the tooltip's content.\n * @docs-private\n */\nlet TooltipComponent = /*#__PURE__*/(() => {\n  class TooltipComponent {\n    constructor(_changeDetectorRef, _elementRef, animationMode) {\n      this._changeDetectorRef = _changeDetectorRef;\n      this._elementRef = _elementRef;\n      /* Whether the tooltip text overflows to multiple lines */\n      this._isMultiline = false;\n      /** Whether interactions on the page should close the tooltip */\n      this._closeOnInteraction = false;\n      /** Whether the tooltip is currently visible. */\n      this._isVisible = false;\n      /** Subject for notifying that the tooltip has been hidden from the view */\n      this._onHide = new Subject();\n      /** Name of the show animation and the class that toggles it. */\n      this._showAnimation = 'mat-mdc-tooltip-show';\n      /** Name of the hide animation and the class that toggles it. */\n      this._hideAnimation = 'mat-mdc-tooltip-hide';\n      this._animationsDisabled = animationMode === 'NoopAnimations';\n    }\n    /**\n     * Shows the tooltip with an animation originating from the provided origin\n     * @param delay Amount of milliseconds to the delay showing the tooltip.\n     */\n    show(delay) {\n      // Cancel the delayed hide if it is scheduled\n      if (this._hideTimeoutId != null) {\n        clearTimeout(this._hideTimeoutId);\n      }\n      this._showTimeoutId = setTimeout(() => {\n        this._toggleVisibility(true);\n        this._showTimeoutId = undefined;\n      }, delay);\n    }\n    /**\n     * Begins the animation to hide the tooltip after the provided delay in ms.\n     * @param delay Amount of milliseconds to delay showing the tooltip.\n     */\n    hide(delay) {\n      // Cancel the delayed show if it is scheduled\n      if (this._showTimeoutId != null) {\n        clearTimeout(this._showTimeoutId);\n      }\n      this._hideTimeoutId = setTimeout(() => {\n        this._toggleVisibility(false);\n        this._hideTimeoutId = undefined;\n      }, delay);\n    }\n    /** Returns an observable that notifies when the tooltip has been hidden from view. */\n    afterHidden() {\n      return this._onHide;\n    }\n    /** Whether the tooltip is being displayed. */\n    isVisible() {\n      return this._isVisible;\n    }\n    ngOnDestroy() {\n      this._cancelPendingAnimations();\n      this._onHide.complete();\n      this._triggerElement = null;\n    }\n    /**\n     * Interactions on the HTML body should close the tooltip immediately as defined in the\n     * material design spec.\n     * https://material.io/design/components/tooltips.html#behavior\n     */\n    _handleBodyInteraction() {\n      if (this._closeOnInteraction) {\n        this.hide(0);\n      }\n    }\n    /**\n     * Marks that the tooltip needs to be checked in the next change detection run.\n     * Mainly used for rendering the initial text before positioning a tooltip, which\n     * can be problematic in components with OnPush change detection.\n     */\n    _markForCheck() {\n      this._changeDetectorRef.markForCheck();\n    }\n    _handleMouseLeave({\n      relatedTarget\n    }) {\n      if (!relatedTarget || !this._triggerElement.contains(relatedTarget)) {\n        if (this.isVisible()) {\n          this.hide(this._mouseLeaveHideDelay);\n        } else {\n          this._finalizeAnimation(false);\n        }\n      }\n    }\n    /**\n     * Callback for when the timeout in this.show() gets completed.\n     * This method is only needed by the mdc-tooltip, and so it is only implemented\n     * in the mdc-tooltip, not here.\n     */\n    _onShow() {\n      this._isMultiline = this._isTooltipMultiline();\n      this._markForCheck();\n    }\n    /** Whether the tooltip text has overflown to the next line */\n    _isTooltipMultiline() {\n      const rect = this._elementRef.nativeElement.getBoundingClientRect();\n      return rect.height > MIN_HEIGHT && rect.width >= MAX_WIDTH;\n    }\n    /** Event listener dispatched when an animation on the tooltip finishes. */\n    _handleAnimationEnd({\n      animationName\n    }) {\n      if (animationName === this._showAnimation || animationName === this._hideAnimation) {\n        this._finalizeAnimation(animationName === this._showAnimation);\n      }\n    }\n    /** Cancels any pending animation sequences. */\n    _cancelPendingAnimations() {\n      if (this._showTimeoutId != null) {\n        clearTimeout(this._showTimeoutId);\n      }\n      if (this._hideTimeoutId != null) {\n        clearTimeout(this._hideTimeoutId);\n      }\n      this._showTimeoutId = this._hideTimeoutId = undefined;\n    }\n    /** Handles the cleanup after an animation has finished. */\n    _finalizeAnimation(toVisible) {\n      if (toVisible) {\n        this._closeOnInteraction = true;\n      } else if (!this.isVisible()) {\n        this._onHide.next();\n      }\n    }\n    /** Toggles the visibility of the tooltip element. */\n    _toggleVisibility(isVisible) {\n      // We set the classes directly here ourselves so that toggling the tooltip state\n      // isn't bound by change detection. This allows us to hide it even if the\n      // view ref has been detached from the CD tree.\n      const tooltip = this._tooltip.nativeElement;\n      const showClass = this._showAnimation;\n      const hideClass = this._hideAnimation;\n      tooltip.classList.remove(isVisible ? hideClass : showClass);\n      tooltip.classList.add(isVisible ? showClass : hideClass);\n      if (this._isVisible !== isVisible) {\n        this._isVisible = isVisible;\n        this._changeDetectorRef.markForCheck();\n      }\n      // It's common for internal apps to disable animations using `* { animation: none !important }`\n      // which can break the opening sequence. Try to detect such cases and work around them.\n      if (isVisible && !this._animationsDisabled && typeof getComputedStyle === 'function') {\n        const styles = getComputedStyle(tooltip);\n        // Use `getPropertyValue` to avoid issues with property renaming.\n        if (styles.getPropertyValue('animation-duration') === '0s' || styles.getPropertyValue('animation-name') === 'none') {\n          this._animationsDisabled = true;\n        }\n      }\n      if (isVisible) {\n        this._onShow();\n      }\n      if (this._animationsDisabled) {\n        tooltip.classList.add('_mat-animation-noopable');\n        this._finalizeAnimation(isVisible);\n      }\n    }\n    static #_ = this.ɵfac = function TooltipComponent_Factory(t) {\n      return new (t || TooltipComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(ANIMATION_MODULE_TYPE, 8));\n    };\n    static #_2 = this.ɵcmp = /* @__PURE__ */i0.ɵɵdefineComponent({\n      type: TooltipComponent,\n      selectors: [[\"mat-tooltip-component\"]],\n      viewQuery: function TooltipComponent_Query(rf, ctx) {\n        if (rf & 1) {\n          i0.ɵɵviewQuery(_c0, 7);\n        }\n        if (rf & 2) {\n          let _t;\n          i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx._tooltip = _t.first);\n        }\n      },\n      hostAttrs: [\"aria-hidden\", \"true\"],\n      hostVars: 2,\n      hostBindings: function TooltipComponent_HostBindings(rf, ctx) {\n        if (rf & 1) {\n          i0.ɵɵlistener(\"mouseleave\", function TooltipComponent_mouseleave_HostBindingHandler($event) {\n            return ctx._handleMouseLeave($event);\n          });\n        }\n        if (rf & 2) {\n          i0.ɵɵstyleProp(\"zoom\", ctx.isVisible() ? 1 : null);\n        }\n      },\n      standalone: true,\n      features: [i0.ɵɵStandaloneFeature],\n      decls: 4,\n      vars: 4,\n      consts: [[\"tooltip\", \"\"], [1, \"mdc-tooltip\", \"mdc-tooltip--shown\", \"mat-mdc-tooltip\", 3, \"animationend\", \"ngClass\"], [1, \"mdc-tooltip__surface\", \"mdc-tooltip__surface-animation\"]],\n      template: function TooltipComponent_Template(rf, ctx) {\n        if (rf & 1) {\n          const _r1 = i0.ɵɵgetCurrentView();\n          i0.ɵɵelementStart(0, \"div\", 1, 0);\n          i0.ɵɵlistener(\"animationend\", function TooltipComponent_Template_div_animationend_0_listener($event) {\n            i0.ɵɵrestoreView(_r1);\n            return i0.ɵɵresetView(ctx._handleAnimationEnd($event));\n          });\n          i0.ɵɵelementStart(2, \"div\", 2);\n          i0.ɵɵtext(3);\n          i0.ɵɵelementEnd()();\n        }\n        if (rf & 2) {\n          i0.ɵɵclassProp(\"mdc-tooltip--multiline\", ctx._isMultiline);\n          i0.ɵɵproperty(\"ngClass\", ctx.tooltipClass);\n          i0.ɵɵadvance(3);\n          i0.ɵɵtextInterpolate(ctx.message);\n        }\n      },\n      dependencies: [NgClass],\n      styles: [\".mdc-tooltip__surface{word-break:break-all;word-break:var(--mdc-tooltip-word-break, normal);overflow-wrap:anywhere}.mdc-tooltip--showing-transition .mdc-tooltip__surface-animation{transition:opacity 150ms 0ms cubic-bezier(0, 0, 0.2, 1),transform 150ms 0ms cubic-bezier(0, 0, 0.2, 1)}.mdc-tooltip--hide-transition .mdc-tooltip__surface-animation{transition:opacity 75ms 0ms cubic-bezier(0.4, 0, 1, 1)}.mdc-tooltip{position:fixed;display:none;z-index:9}.mdc-tooltip-wrapper--rich{position:relative}.mdc-tooltip--shown,.mdc-tooltip--showing,.mdc-tooltip--hide{display:inline-flex}.mdc-tooltip--shown.mdc-tooltip--rich,.mdc-tooltip--showing.mdc-tooltip--rich,.mdc-tooltip--hide.mdc-tooltip--rich{display:inline-block;left:-320px;position:absolute}.mdc-tooltip__surface{line-height:16px;padding:4px 8px;min-width:40px;max-width:200px;min-height:24px;max-height:40vh;box-sizing:border-box;overflow:hidden;text-align:center}.mdc-tooltip__surface::before{position:absolute;box-sizing:border-box;width:100%;height:100%;top:0;left:0;border:1px solid rgba(0,0,0,0);border-radius:inherit;content:\\\"\\\";pointer-events:none}@media screen and (forced-colors: active){.mdc-tooltip__surface::before{border-color:CanvasText}}.mdc-tooltip--rich .mdc-tooltip__surface{align-items:flex-start;display:flex;flex-direction:column;min-height:24px;min-width:40px;max-width:320px;position:relative}.mdc-tooltip--multiline .mdc-tooltip__surface{text-align:left}[dir=rtl] .mdc-tooltip--multiline .mdc-tooltip__surface,.mdc-tooltip--multiline .mdc-tooltip__surface[dir=rtl]{text-align:right}.mdc-tooltip__surface .mdc-tooltip__title{margin:0 8px}.mdc-tooltip__surface .mdc-tooltip__content{max-width:calc(200px - 2*8px);margin:8px;text-align:left}[dir=rtl] .mdc-tooltip__surface .mdc-tooltip__content,.mdc-tooltip__surface .mdc-tooltip__content[dir=rtl]{text-align:right}.mdc-tooltip--rich .mdc-tooltip__surface .mdc-tooltip__content{max-width:calc(320px - 2*8px);align-self:stretch}.mdc-tooltip__surface .mdc-tooltip__content-link{text-decoration:none}.mdc-tooltip--rich-actions,.mdc-tooltip__content,.mdc-tooltip__title{z-index:1}.mdc-tooltip__surface-animation{opacity:0;transform:scale(0.8);will-change:transform,opacity}.mdc-tooltip--shown .mdc-tooltip__surface-animation{transform:scale(1);opacity:1}.mdc-tooltip--hide .mdc-tooltip__surface-animation{transform:scale(1)}.mdc-tooltip__caret-surface-top,.mdc-tooltip__caret-surface-bottom{position:absolute;height:24px;width:24px;transform:rotate(35deg) skewY(20deg) scaleX(0.9396926208)}.mdc-tooltip__caret-surface-top .mdc-elevation-overlay,.mdc-tooltip__caret-surface-bottom .mdc-elevation-overlay{width:100%;height:100%;top:0;left:0}.mdc-tooltip__caret-surface-bottom{box-shadow:0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12);outline:1px solid rgba(0,0,0,0);z-index:-1}@media screen and (forced-colors: active){.mdc-tooltip__caret-surface-bottom{outline-color:CanvasText}}.mat-mdc-tooltip .mdc-tooltip__surface{background-color:var(--mdc-plain-tooltip-container-color)}.mat-mdc-tooltip .mdc-tooltip__surface{border-radius:var(--mdc-plain-tooltip-container-shape)}.mat-mdc-tooltip .mdc-tooltip__caret-surface-top,.mat-mdc-tooltip .mdc-tooltip__caret-surface-bottom{border-radius:var(--mdc-plain-tooltip-container-shape)}.mat-mdc-tooltip .mdc-tooltip__surface{color:var(--mdc-plain-tooltip-supporting-text-color)}.mat-mdc-tooltip .mdc-tooltip__surface{font-family:var(--mdc-plain-tooltip-supporting-text-font);line-height:var(--mdc-plain-tooltip-supporting-text-line-height);font-size:var(--mdc-plain-tooltip-supporting-text-size);font-weight:var(--mdc-plain-tooltip-supporting-text-weight);letter-spacing:var(--mdc-plain-tooltip-supporting-text-tracking)}.mat-mdc-tooltip{position:relative;transform:scale(0)}.mat-mdc-tooltip::before{content:\\\"\\\";top:0;right:0;bottom:0;left:0;z-index:-1;position:absolute}.mat-mdc-tooltip-panel-below .mat-mdc-tooltip::before{top:-8px}.mat-mdc-tooltip-panel-above .mat-mdc-tooltip::before{bottom:-8px}.mat-mdc-tooltip-panel-right .mat-mdc-tooltip::before{left:-8px}.mat-mdc-tooltip-panel-left .mat-mdc-tooltip::before{right:-8px}.mat-mdc-tooltip._mat-animation-noopable{animation:none;transform:scale(1)}.mat-mdc-tooltip-panel.mat-mdc-tooltip-panel-non-interactive{pointer-events:none}@keyframes mat-mdc-tooltip-show{0%{opacity:0;transform:scale(0.8)}100%{opacity:1;transform:scale(1)}}@keyframes mat-mdc-tooltip-hide{0%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(0.8)}}.mat-mdc-tooltip-show{animation:mat-mdc-tooltip-show 150ms cubic-bezier(0, 0, 0.2, 1) forwards}.mat-mdc-tooltip-hide{animation:mat-mdc-tooltip-hide 75ms cubic-bezier(0.4, 0, 1, 1) forwards}\"],\n      encapsulation: 2,\n      changeDetection: 0\n    });\n  }\n  return TooltipComponent;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * Animations used by MatTooltip.\n * @docs-private\n */\nconst matTooltipAnimations = {\n  /** Animation that transitions a tooltip in and out. */\n  tooltipState: /*#__PURE__*/trigger('state', [\n  /*#__PURE__*/\n  // TODO(crisbeto): these values are based on MDC's CSS.\n  // We should be able to use their styles directly once we land #19432.\n  state('initial, void, hidden', /*#__PURE__*/style({\n    opacity: 0,\n    transform: 'scale(0.8)'\n  })), /*#__PURE__*/state('visible', /*#__PURE__*/style({\n    transform: 'scale(1)'\n  })), /*#__PURE__*/transition('* => visible', /*#__PURE__*/animate('150ms cubic-bezier(0, 0, 0.2, 1)')), /*#__PURE__*/transition('* => hidden', /*#__PURE__*/animate('75ms cubic-bezier(0.4, 0, 1, 1)'))])\n};\nlet MatTooltipModule = /*#__PURE__*/(() => {\n  class MatTooltipModule {\n    static #_ = this.ɵfac = function MatTooltipModule_Factory(t) {\n      return new (t || MatTooltipModule)();\n    };\n    static #_2 = this.ɵmod = /* @__PURE__ */i0.ɵɵdefineNgModule({\n      type: MatTooltipModule\n    });\n    static #_3 = this.ɵinj = /* @__PURE__ */i0.ɵɵdefineInjector({\n      providers: [MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY_PROVIDER],\n      imports: [A11yModule, CommonModule, OverlayModule, MatCommonModule, MatCommonModule, CdkScrollableModule]\n    });\n  }\n  return MatTooltipModule;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * Generated bundle index. Do not edit.\n */\n\nexport { MAT_TOOLTIP_DEFAULT_OPTIONS, MAT_TOOLTIP_DEFAULT_OPTIONS_FACTORY, MAT_TOOLTIP_SCROLL_STRATEGY, MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY, MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY_PROVIDER, MatTooltip, MatTooltipModule, SCROLL_THROTTLE_MS, TOOLTIP_PANEL_CLASS, TooltipComponent, getMatTooltipInvalidPositionError, matTooltipAnimations };\n//# sourceMappingURL=tooltip.mjs.map","map":null,"metadata":{},"sourceType":"module","externalDependencies":[]}