{"ast":null,"code":"import * as i1 from '@angular/cdk/scrolling';\nimport { ScrollingModule } from '@angular/cdk/scrolling';\nexport { CdkScrollable, ScrollDispatcher, ViewportRuler } from '@angular/cdk/scrolling';\nimport * as i6 from '@angular/common';\nimport { DOCUMENT } from '@angular/common';\nimport * as i0 from '@angular/core';\nimport { Injectable, Inject, Optional, ElementRef, ApplicationRef, ANIMATION_MODULE_TYPE, InjectionToken, inject, Directive, NgZone, EventEmitter, booleanAttribute, Input, Output, NgModule } from '@angular/core';\nimport { coerceCssPixelValue, coerceArray } from '@angular/cdk/coercion';\nimport * as i1$1 from '@angular/cdk/platform';\nimport { supportsScrollBehavior, _getEventTarget, _isTestEnvironment } from '@angular/cdk/platform';\nimport { filter, take, takeUntil, takeWhile } from 'rxjs/operators';\nimport * as i5 from '@angular/cdk/bidi';\nimport { BidiModule } from '@angular/cdk/bidi';\nimport { DomPortalOutlet, TemplatePortal, PortalModule } from '@angular/cdk/portal';\nimport { Subject, Subscription, merge } from 'rxjs';\nimport { ESCAPE, hasModifierKey } from '@angular/cdk/keycodes';\nconst scrollBehaviorSupported = /*#__PURE__*/supportsScrollBehavior();\n/**\n * Strategy that will prevent the user from scrolling while the overlay is visible.\n */\nclass BlockScrollStrategy {\n  constructor(_viewportRuler, document) {\n    this._viewportRuler = _viewportRuler;\n    this._previousHTMLStyles = {\n      top: '',\n      left: ''\n    };\n    this._isEnabled = false;\n    this._document = document;\n  }\n  /** Attaches this scroll strategy to an overlay. */\n  attach() {}\n  /** Blocks page-level scroll while the attached overlay is open. */\n  enable() {\n    if (this._canBeEnabled()) {\n      const root = this._document.documentElement;\n      this._previousScrollPosition = this._viewportRuler.getViewportScrollPosition();\n      // Cache the previous inline styles in case the user had set them.\n      this._previousHTMLStyles.left = root.style.left || '';\n      this._previousHTMLStyles.top = root.style.top || '';\n      // Note: we're using the `html` node, instead of the `body`, because the `body` may\n      // have the user agent margin, whereas the `html` is guaranteed not to have one.\n      root.style.left = coerceCssPixelValue(-this._previousScrollPosition.left);\n      root.style.top = coerceCssPixelValue(-this._previousScrollPosition.top);\n      root.classList.add('cdk-global-scrollblock');\n      this._isEnabled = true;\n    }\n  }\n  /** Unblocks page-level scroll while the attached overlay is open. */\n  disable() {\n    if (this._isEnabled) {\n      const html = this._document.documentElement;\n      const body = this._document.body;\n      const htmlStyle = html.style;\n      const bodyStyle = body.style;\n      const previousHtmlScrollBehavior = htmlStyle.scrollBehavior || '';\n      const previousBodyScrollBehavior = bodyStyle.scrollBehavior || '';\n      this._isEnabled = false;\n      htmlStyle.left = this._previousHTMLStyles.left;\n      htmlStyle.top = this._previousHTMLStyles.top;\n      html.classList.remove('cdk-global-scrollblock');\n      // Disable user-defined smooth scrolling temporarily while we restore the scroll position.\n      // See https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior\n      // Note that we don't mutate the property if the browser doesn't support `scroll-behavior`,\n      // because it can throw off feature detections in `supportsScrollBehavior` which\n      // checks for `'scrollBehavior' in documentElement.style`.\n      if (scrollBehaviorSupported) {\n        htmlStyle.scrollBehavior = bodyStyle.scrollBehavior = 'auto';\n      }\n      window.scroll(this._previousScrollPosition.left, this._previousScrollPosition.top);\n      if (scrollBehaviorSupported) {\n        htmlStyle.scrollBehavior = previousHtmlScrollBehavior;\n        bodyStyle.scrollBehavior = previousBodyScrollBehavior;\n      }\n    }\n  }\n  _canBeEnabled() {\n    // Since the scroll strategies can't be singletons, we have to use a global CSS class\n    // (`cdk-global-scrollblock`) to make sure that we don't try to disable global\n    // scrolling multiple times.\n    const html = this._document.documentElement;\n    if (html.classList.contains('cdk-global-scrollblock') || this._isEnabled) {\n      return false;\n    }\n    const body = this._document.body;\n    const viewport = this._viewportRuler.getViewportSize();\n    return body.scrollHeight > viewport.height || body.scrollWidth > viewport.width;\n  }\n}\n\n/**\n * Returns an error to be thrown when attempting to attach an already-attached scroll strategy.\n */\nfunction getMatScrollStrategyAlreadyAttachedError() {\n  return Error(`Scroll strategy has already been attached.`);\n}\n\n/**\n * Strategy that will close the overlay as soon as the user starts scrolling.\n */\nclass CloseScrollStrategy {\n  constructor(_scrollDispatcher, _ngZone, _viewportRuler, _config) {\n    this._scrollDispatcher = _scrollDispatcher;\n    this._ngZone = _ngZone;\n    this._viewportRuler = _viewportRuler;\n    this._config = _config;\n    this._scrollSubscription = null;\n    /** Detaches the overlay ref and disables the scroll strategy. */\n    this._detach = () => {\n      this.disable();\n      if (this._overlayRef.hasAttached()) {\n        this._ngZone.run(() => this._overlayRef.detach());\n      }\n    };\n  }\n  /** Attaches this scroll strategy to an overlay. */\n  attach(overlayRef) {\n    if (this._overlayRef && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n      throw getMatScrollStrategyAlreadyAttachedError();\n    }\n    this._overlayRef = overlayRef;\n  }\n  /** Enables the closing of the attached overlay on scroll. */\n  enable() {\n    if (this._scrollSubscription) {\n      return;\n    }\n    const stream = this._scrollDispatcher.scrolled(0).pipe(filter(scrollable => {\n      return !scrollable || !this._overlayRef.overlayElement.contains(scrollable.getElementRef().nativeElement);\n    }));\n    if (this._config && this._config.threshold && this._config.threshold > 1) {\n      this._initialScrollPosition = this._viewportRuler.getViewportScrollPosition().top;\n      this._scrollSubscription = stream.subscribe(() => {\n        const scrollPosition = this._viewportRuler.getViewportScrollPosition().top;\n        if (Math.abs(scrollPosition - this._initialScrollPosition) > this._config.threshold) {\n          this._detach();\n        } else {\n          this._overlayRef.updatePosition();\n        }\n      });\n    } else {\n      this._scrollSubscription = stream.subscribe(this._detach);\n    }\n  }\n  /** Disables the closing the attached overlay on scroll. */\n  disable() {\n    if (this._scrollSubscription) {\n      this._scrollSubscription.unsubscribe();\n      this._scrollSubscription = null;\n    }\n  }\n  detach() {\n    this.disable();\n    this._overlayRef = null;\n  }\n}\n\n/** Scroll strategy that doesn't do anything. */\nclass NoopScrollStrategy {\n  /** Does nothing, as this scroll strategy is a no-op. */\n  enable() {}\n  /** Does nothing, as this scroll strategy is a no-op. */\n  disable() {}\n  /** Does nothing, as this scroll strategy is a no-op. */\n  attach() {}\n}\n\n/**\n * Gets whether an element is scrolled outside of view by any of its parent scrolling containers.\n * @param element Dimensions of the element (from getBoundingClientRect)\n * @param scrollContainers Dimensions of element's scrolling containers (from getBoundingClientRect)\n * @returns Whether the element is scrolled out of view\n * @docs-private\n */\nfunction isElementScrolledOutsideView(element, scrollContainers) {\n  return scrollContainers.some(containerBounds => {\n    const outsideAbove = element.bottom < containerBounds.top;\n    const outsideBelow = element.top > containerBounds.bottom;\n    const outsideLeft = element.right < containerBounds.left;\n    const outsideRight = element.left > containerBounds.right;\n    return outsideAbove || outsideBelow || outsideLeft || outsideRight;\n  });\n}\n/**\n * Gets whether an element is clipped by any of its scrolling containers.\n * @param element Dimensions of the element (from getBoundingClientRect)\n * @param scrollContainers Dimensions of element's scrolling containers (from getBoundingClientRect)\n * @returns Whether the element is clipped\n * @docs-private\n */\nfunction isElementClippedByScrolling(element, scrollContainers) {\n  return scrollContainers.some(scrollContainerRect => {\n    const clippedAbove = element.top < scrollContainerRect.top;\n    const clippedBelow = element.bottom > scrollContainerRect.bottom;\n    const clippedLeft = element.left < scrollContainerRect.left;\n    const clippedRight = element.right > scrollContainerRect.right;\n    return clippedAbove || clippedBelow || clippedLeft || clippedRight;\n  });\n}\n\n/**\n * Strategy that will update the element position as the user is scrolling.\n */\nclass RepositionScrollStrategy {\n  constructor(_scrollDispatcher, _viewportRuler, _ngZone, _config) {\n    this._scrollDispatcher = _scrollDispatcher;\n    this._viewportRuler = _viewportRuler;\n    this._ngZone = _ngZone;\n    this._config = _config;\n    this._scrollSubscription = null;\n  }\n  /** Attaches this scroll strategy to an overlay. */\n  attach(overlayRef) {\n    if (this._overlayRef && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n      throw getMatScrollStrategyAlreadyAttachedError();\n    }\n    this._overlayRef = overlayRef;\n  }\n  /** Enables repositioning of the attached overlay on scroll. */\n  enable() {\n    if (!this._scrollSubscription) {\n      const throttle = this._config ? this._config.scrollThrottle : 0;\n      this._scrollSubscription = this._scrollDispatcher.scrolled(throttle).subscribe(() => {\n        this._overlayRef.updatePosition();\n        // TODO(crisbeto): make `close` on by default once all components can handle it.\n        if (this._config && this._config.autoClose) {\n          const overlayRect = this._overlayRef.overlayElement.getBoundingClientRect();\n          const {\n            width,\n            height\n          } = this._viewportRuler.getViewportSize();\n          // TODO(crisbeto): include all ancestor scroll containers here once\n          // we have a way of exposing the trigger element to the scroll strategy.\n          const parentRects = [{\n            width,\n            height,\n            bottom: height,\n            right: width,\n            top: 0,\n            left: 0\n          }];\n          if (isElementScrolledOutsideView(overlayRect, parentRects)) {\n            this.disable();\n            this._ngZone.run(() => this._overlayRef.detach());\n          }\n        }\n      });\n    }\n  }\n  /** Disables repositioning of the attached overlay on scroll. */\n  disable() {\n    if (this._scrollSubscription) {\n      this._scrollSubscription.unsubscribe();\n      this._scrollSubscription = null;\n    }\n  }\n  detach() {\n    this.disable();\n    this._overlayRef = null;\n  }\n}\n\n/**\n * Options for how an overlay will handle scrolling.\n *\n * Users can provide a custom value for `ScrollStrategyOptions` to replace the default\n * behaviors. This class primarily acts as a factory for ScrollStrategy instances.\n */\nlet ScrollStrategyOptions = /*#__PURE__*/(() => {\n  class ScrollStrategyOptions {\n    constructor(_scrollDispatcher, _viewportRuler, _ngZone, document) {\n      this._scrollDispatcher = _scrollDispatcher;\n      this._viewportRuler = _viewportRuler;\n      this._ngZone = _ngZone;\n      /** Do nothing on scroll. */\n      this.noop = () => new NoopScrollStrategy();\n      /**\n       * Close the overlay as soon as the user scrolls.\n       * @param config Configuration to be used inside the scroll strategy.\n       */\n      this.close = config => new CloseScrollStrategy(this._scrollDispatcher, this._ngZone, this._viewportRuler, config);\n      /** Block scrolling. */\n      this.block = () => new BlockScrollStrategy(this._viewportRuler, this._document);\n      /**\n       * Update the overlay's position on scroll.\n       * @param config Configuration to be used inside the scroll strategy.\n       * Allows debouncing the reposition calls.\n       */\n      this.reposition = config => new RepositionScrollStrategy(this._scrollDispatcher, this._viewportRuler, this._ngZone, config);\n      this._document = document;\n    }\n    static #_ = this.ɵfac = function ScrollStrategyOptions_Factory(t) {\n      return new (t || ScrollStrategyOptions)(i0.ɵɵinject(i1.ScrollDispatcher), i0.ɵɵinject(i1.ViewportRuler), i0.ɵɵinject(i0.NgZone), i0.ɵɵinject(DOCUMENT));\n    };\n    static #_2 = this.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n      token: ScrollStrategyOptions,\n      factory: ScrollStrategyOptions.ɵfac,\n      providedIn: 'root'\n    });\n  }\n  return ScrollStrategyOptions;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/** Initial configuration used when creating an overlay. */\nclass OverlayConfig {\n  constructor(config) {\n    /** Strategy to be used when handling scroll events while the overlay is open. */\n    this.scrollStrategy = new NoopScrollStrategy();\n    /** Custom class to add to the overlay pane. */\n    this.panelClass = '';\n    /** Whether the overlay has a backdrop. */\n    this.hasBackdrop = false;\n    /** Custom class to add to the backdrop */\n    this.backdropClass = 'cdk-overlay-dark-backdrop';\n    /**\n     * Whether the overlay should be disposed of when the user goes backwards/forwards in history.\n     * Note that this usually doesn't include clicking on links (unless the user is using\n     * the `HashLocationStrategy`).\n     */\n    this.disposeOnNavigation = false;\n    if (config) {\n      // Use `Iterable` instead of `Array` because TypeScript, as of 3.6.3,\n      // loses the array generic type in the `for of`. But we *also* have to use `Array` because\n      // typescript won't iterate over an `Iterable` unless you compile with `--downlevelIteration`\n      const configKeys = Object.keys(config);\n      for (const key of configKeys) {\n        if (config[key] !== undefined) {\n          // TypeScript, as of version 3.5, sees the left-hand-side of this expression\n          // as \"I don't know *which* key this is, so the only valid value is the intersection\n          // of all the possible values.\" In this case, that happens to be `undefined`. TypeScript\n          // is not smart enough to see that the right-hand-side is actually an access of the same\n          // exact type with the same exact key, meaning that the value type must be identical.\n          // So we use `any` to work around this.\n          this[key] = config[key];\n        }\n      }\n    }\n  }\n}\n\n/** The points of the origin element and the overlay element to connect. */\nclass ConnectionPositionPair {\n  constructor(origin, overlay, /** Offset along the X axis. */\n  offsetX, /** Offset along the Y axis. */\n  offsetY, /** Class(es) to be applied to the panel while this position is active. */\n  panelClass) {\n    this.offsetX = offsetX;\n    this.offsetY = offsetY;\n    this.panelClass = panelClass;\n    this.originX = origin.originX;\n    this.originY = origin.originY;\n    this.overlayX = overlay.overlayX;\n    this.overlayY = overlay.overlayY;\n  }\n}\n/**\n * Set of properties regarding the position of the origin and overlay relative to the viewport\n * with respect to the containing Scrollable elements.\n *\n * The overlay and origin are clipped if any part of their bounding client rectangle exceeds the\n * bounds of any one of the strategy's Scrollable's bounding client rectangle.\n *\n * The overlay and origin are outside view if there is no overlap between their bounding client\n * rectangle and any one of the strategy's Scrollable's bounding client rectangle.\n *\n *       -----------                    -----------\n *       | outside |                    | clipped |\n *       |  view   |              --------------------------\n *       |         |              |     |         |        |\n *       ----------               |     -----------        |\n *  --------------------------    |                        |\n *  |                        |    |      Scrollable        |\n *  |                        |    |                        |\n *  |                        |     --------------------------\n *  |      Scrollable        |\n *  |                        |\n *  --------------------------\n *\n *  @docs-private\n */\nclass ScrollingVisibility {}\n/** The change event emitted by the strategy when a fallback position is used. */\nclass ConnectedOverlayPositionChange {\n  constructor( /** The position used as a result of this change. */\n  connectionPair, /** @docs-private */\n  scrollableViewProperties) {\n    this.connectionPair = connectionPair;\n    this.scrollableViewProperties = scrollableViewProperties;\n  }\n}\n/**\n * Validates whether a vertical position property matches the expected values.\n * @param property Name of the property being validated.\n * @param value Value of the property being validated.\n * @docs-private\n */\nfunction validateVerticalPosition(property, value) {\n  if (value !== 'top' && value !== 'bottom' && value !== 'center') {\n    throw Error(`ConnectedPosition: Invalid ${property} \"${value}\". ` + `Expected \"top\", \"bottom\" or \"center\".`);\n  }\n}\n/**\n * Validates whether a horizontal position property matches the expected values.\n * @param property Name of the property being validated.\n * @param value Value of the property being validated.\n * @docs-private\n */\nfunction validateHorizontalPosition(property, value) {\n  if (value !== 'start' && value !== 'end' && value !== 'center') {\n    throw Error(`ConnectedPosition: Invalid ${property} \"${value}\". ` + `Expected \"start\", \"end\" or \"center\".`);\n  }\n}\n\n/**\n * Service for dispatching events that land on the body to appropriate overlay ref,\n * if any. It maintains a list of attached overlays to determine best suited overlay based\n * on event target and order of overlay opens.\n */\nlet BaseOverlayDispatcher = /*#__PURE__*/(() => {\n  class BaseOverlayDispatcher {\n    constructor(document) {\n      /** Currently attached overlays in the order they were attached. */\n      this._attachedOverlays = [];\n      this._document = document;\n    }\n    ngOnDestroy() {\n      this.detach();\n    }\n    /** Add a new overlay to the list of attached overlay refs. */\n    add(overlayRef) {\n      // Ensure that we don't get the same overlay multiple times.\n      this.remove(overlayRef);\n      this._attachedOverlays.push(overlayRef);\n    }\n    /** Remove an overlay from the list of attached overlay refs. */\n    remove(overlayRef) {\n      const index = this._attachedOverlays.indexOf(overlayRef);\n      if (index > -1) {\n        this._attachedOverlays.splice(index, 1);\n      }\n      // Remove the global listener once there are no more overlays.\n      if (this._attachedOverlays.length === 0) {\n        this.detach();\n      }\n    }\n    static #_ = this.ɵfac = function BaseOverlayDispatcher_Factory(t) {\n      return new (t || BaseOverlayDispatcher)(i0.ɵɵinject(DOCUMENT));\n    };\n    static #_2 = this.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n      token: BaseOverlayDispatcher,\n      factory: BaseOverlayDispatcher.ɵfac,\n      providedIn: 'root'\n    });\n  }\n  return BaseOverlayDispatcher;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * Service for dispatching keyboard events that land on the body to appropriate overlay ref,\n * if any. It maintains a list of attached overlays to determine best suited overlay based\n * on event target and order of overlay opens.\n */\nlet OverlayKeyboardDispatcher = /*#__PURE__*/(() => {\n  class OverlayKeyboardDispatcher extends BaseOverlayDispatcher {\n    constructor(document, /** @breaking-change 14.0.0 _ngZone will be required. */\n    _ngZone) {\n      super(document);\n      this._ngZone = _ngZone;\n      /** Keyboard event listener that will be attached to the body. */\n      this._keydownListener = event => {\n        const overlays = this._attachedOverlays;\n        for (let i = overlays.length - 1; i > -1; i--) {\n          // Dispatch the keydown event to the top overlay which has subscribers to its keydown events.\n          // We want to target the most recent overlay, rather than trying to match where the event came\n          // from, because some components might open an overlay, but keep focus on a trigger element\n          // (e.g. for select and autocomplete). We skip overlays without keydown event subscriptions,\n          // because we don't want overlays that don't handle keyboard events to block the ones below\n          // them that do.\n          if (overlays[i]._keydownEvents.observers.length > 0) {\n            const keydownEvents = overlays[i]._keydownEvents;\n            /** @breaking-change 14.0.0 _ngZone will be required. */\n            if (this._ngZone) {\n              this._ngZone.run(() => keydownEvents.next(event));\n            } else {\n              keydownEvents.next(event);\n            }\n            break;\n          }\n        }\n      };\n    }\n    /** Add a new overlay to the list of attached overlay refs. */\n    add(overlayRef) {\n      super.add(overlayRef);\n      // Lazily start dispatcher once first overlay is added\n      if (!this._isAttached) {\n        /** @breaking-change 14.0.0 _ngZone will be required. */\n        if (this._ngZone) {\n          this._ngZone.runOutsideAngular(() => this._document.body.addEventListener('keydown', this._keydownListener));\n        } else {\n          this._document.body.addEventListener('keydown', this._keydownListener);\n        }\n        this._isAttached = true;\n      }\n    }\n    /** Detaches the global keyboard event listener. */\n    detach() {\n      if (this._isAttached) {\n        this._document.body.removeEventListener('keydown', this._keydownListener);\n        this._isAttached = false;\n      }\n    }\n    static #_ = this.ɵfac = function OverlayKeyboardDispatcher_Factory(t) {\n      return new (t || OverlayKeyboardDispatcher)(i0.ɵɵinject(DOCUMENT), i0.ɵɵinject(i0.NgZone, 8));\n    };\n    static #_2 = this.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n      token: OverlayKeyboardDispatcher,\n      factory: OverlayKeyboardDispatcher.ɵfac,\n      providedIn: 'root'\n    });\n  }\n  return OverlayKeyboardDispatcher;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * Service for dispatching mouse click events that land on the body to appropriate overlay ref,\n * if any. It maintains a list of attached overlays to determine best suited overlay based\n * on event target and order of overlay opens.\n */\nlet OverlayOutsideClickDispatcher = /*#__PURE__*/(() => {\n  class OverlayOutsideClickDispatcher extends BaseOverlayDispatcher {\n    constructor(document, _platform, /** @breaking-change 14.0.0 _ngZone will be required. */\n    _ngZone) {\n      super(document);\n      this._platform = _platform;\n      this._ngZone = _ngZone;\n      this._cursorStyleIsSet = false;\n      /** Store pointerdown event target to track origin of click. */\n      this._pointerDownListener = event => {\n        this._pointerDownEventTarget = _getEventTarget(event);\n      };\n      /** Click event listener that will be attached to the body propagate phase. */\n      this._clickListener = event => {\n        const target = _getEventTarget(event);\n        // In case of a click event, we want to check the origin of the click\n        // (e.g. in case where a user starts a click inside the overlay and\n        // releases the click outside of it).\n        // This is done by using the event target of the preceding pointerdown event.\n        // Every click event caused by a pointer device has a preceding pointerdown\n        // event, unless the click was programmatically triggered (e.g. in a unit test).\n        const origin = event.type === 'click' && this._pointerDownEventTarget ? this._pointerDownEventTarget : target;\n        // Reset the stored pointerdown event target, to avoid having it interfere\n        // in subsequent events.\n        this._pointerDownEventTarget = null;\n        // We copy the array because the original may be modified asynchronously if the\n        // outsidePointerEvents listener decides to detach overlays resulting in index errors inside\n        // the for loop.\n        const overlays = this._attachedOverlays.slice();\n        // Dispatch the mouse event to the top overlay which has subscribers to its mouse events.\n        // We want to target all overlays for which the click could be considered as outside click.\n        // As soon as we reach an overlay for which the click is not outside click we break off\n        // the loop.\n        for (let i = overlays.length - 1; i > -1; i--) {\n          const overlayRef = overlays[i];\n          if (overlayRef._outsidePointerEvents.observers.length < 1 || !overlayRef.hasAttached()) {\n            continue;\n          }\n          // If it's a click inside the overlay, just break - we should do nothing\n          // If it's an outside click (both origin and target of the click) dispatch the mouse event,\n          // and proceed with the next overlay\n          if (overlayRef.overlayElement.contains(target) || overlayRef.overlayElement.contains(origin)) {\n            break;\n          }\n          const outsidePointerEvents = overlayRef._outsidePointerEvents;\n          /** @breaking-change 14.0.0 _ngZone will be required. */\n          if (this._ngZone) {\n            this._ngZone.run(() => outsidePointerEvents.next(event));\n          } else {\n            outsidePointerEvents.next(event);\n          }\n        }\n      };\n    }\n    /** Add a new overlay to the list of attached overlay refs. */\n    add(overlayRef) {\n      super.add(overlayRef);\n      // Safari on iOS does not generate click events for non-interactive\n      // elements. However, we want to receive a click for any element outside\n      // the overlay. We can force a \"clickable\" state by setting\n      // `cursor: pointer` on the document body. See:\n      // https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event#Safari_Mobile\n      // https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html\n      if (!this._isAttached) {\n        const body = this._document.body;\n        /** @breaking-change 14.0.0 _ngZone will be required. */\n        if (this._ngZone) {\n          this._ngZone.runOutsideAngular(() => this._addEventListeners(body));\n        } else {\n          this._addEventListeners(body);\n        }\n        // click event is not fired on iOS. To make element \"clickable\" we are\n        // setting the cursor to pointer\n        if (this._platform.IOS && !this._cursorStyleIsSet) {\n          this._cursorOriginalValue = body.style.cursor;\n          body.style.cursor = 'pointer';\n          this._cursorStyleIsSet = true;\n        }\n        this._isAttached = true;\n      }\n    }\n    /** Detaches the global keyboard event listener. */\n    detach() {\n      if (this._isAttached) {\n        const body = this._document.body;\n        body.removeEventListener('pointerdown', this._pointerDownListener, true);\n        body.removeEventListener('click', this._clickListener, true);\n        body.removeEventListener('auxclick', this._clickListener, true);\n        body.removeEventListener('contextmenu', this._clickListener, true);\n        if (this._platform.IOS && this._cursorStyleIsSet) {\n          body.style.cursor = this._cursorOriginalValue;\n          this._cursorStyleIsSet = false;\n        }\n        this._isAttached = false;\n      }\n    }\n    _addEventListeners(body) {\n      body.addEventListener('pointerdown', this._pointerDownListener, true);\n      body.addEventListener('click', this._clickListener, true);\n      body.addEventListener('auxclick', this._clickListener, true);\n      body.addEventListener('contextmenu', this._clickListener, true);\n    }\n    static #_ = this.ɵfac = function OverlayOutsideClickDispatcher_Factory(t) {\n      return new (t || OverlayOutsideClickDispatcher)(i0.ɵɵinject(DOCUMENT), i0.ɵɵinject(i1$1.Platform), i0.ɵɵinject(i0.NgZone, 8));\n    };\n    static #_2 = this.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n      token: OverlayOutsideClickDispatcher,\n      factory: OverlayOutsideClickDispatcher.ɵfac,\n      providedIn: 'root'\n    });\n  }\n  return OverlayOutsideClickDispatcher;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/** Container inside which all overlays will render. */\nlet OverlayContainer = /*#__PURE__*/(() => {\n  class OverlayContainer {\n    constructor(document, _platform) {\n      this._platform = _platform;\n      this._document = document;\n    }\n    ngOnDestroy() {\n      this._containerElement?.remove();\n    }\n    /**\n     * This method returns the overlay container element. It will lazily\n     * create the element the first time it is called to facilitate using\n     * the container in non-browser environments.\n     * @returns the container element\n     */\n    getContainerElement() {\n      if (!this._containerElement) {\n        this._createContainer();\n      }\n      return this._containerElement;\n    }\n    /**\n     * Create the overlay container element, which is simply a div\n     * with the 'cdk-overlay-container' class on the document body.\n     */\n    _createContainer() {\n      const containerClass = 'cdk-overlay-container';\n      // TODO(crisbeto): remove the testing check once we have an overlay testing\n      // module or Angular starts tearing down the testing `NgModule`. See:\n      // https://github.com/angular/angular/issues/18831\n      if (this._platform.isBrowser || _isTestEnvironment()) {\n        const oppositePlatformContainers = this._document.querySelectorAll(`.${containerClass}[platform=\"server\"], ` + `.${containerClass}[platform=\"test\"]`);\n        // Remove any old containers from the opposite platform.\n        // This can happen when transitioning from the server to the client.\n        for (let i = 0; i < oppositePlatformContainers.length; i++) {\n          oppositePlatformContainers[i].remove();\n        }\n      }\n      const container = this._document.createElement('div');\n      container.classList.add(containerClass);\n      // A long time ago we kept adding new overlay containers whenever a new app was instantiated,\n      // but at some point we added logic which clears the duplicate ones in order to avoid leaks.\n      // The new logic was a little too aggressive since it was breaking some legitimate use cases.\n      // To mitigate the problem we made it so that only containers from a different platform are\n      // cleared, but the side-effect was that people started depending on the overly-aggressive\n      // logic to clean up their tests for them. Until we can introduce an overlay-specific testing\n      // module which does the cleanup, we try to detect that we're in a test environment and we\n      // always clear the container. See #17006.\n      // TODO(crisbeto): remove the test environment check once we have an overlay testing module.\n      if (_isTestEnvironment()) {\n        container.setAttribute('platform', 'test');\n      } else if (!this._platform.isBrowser) {\n        container.setAttribute('platform', 'server');\n      }\n      this._document.body.appendChild(container);\n      this._containerElement = container;\n    }\n    static #_ = this.ɵfac = function OverlayContainer_Factory(t) {\n      return new (t || OverlayContainer)(i0.ɵɵinject(DOCUMENT), i0.ɵɵinject(i1$1.Platform));\n    };\n    static #_2 = this.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n      token: OverlayContainer,\n      factory: OverlayContainer.ɵfac,\n      providedIn: 'root'\n    });\n  }\n  return OverlayContainer;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * Reference to an overlay that has been created with the Overlay service.\n * Used to manipulate or dispose of said overlay.\n */\nclass OverlayRef {\n  constructor(_portalOutlet, _host, _pane, _config, _ngZone, _keyboardDispatcher, _document, _location, _outsideClickDispatcher, _animationsDisabled = false) {\n    this._portalOutlet = _portalOutlet;\n    this._host = _host;\n    this._pane = _pane;\n    this._config = _config;\n    this._ngZone = _ngZone;\n    this._keyboardDispatcher = _keyboardDispatcher;\n    this._document = _document;\n    this._location = _location;\n    this._outsideClickDispatcher = _outsideClickDispatcher;\n    this._animationsDisabled = _animationsDisabled;\n    this._backdropElement = null;\n    this._backdropClick = new Subject();\n    this._attachments = new Subject();\n    this._detachments = new Subject();\n    this._locationChanges = Subscription.EMPTY;\n    this._backdropClickHandler = event => this._backdropClick.next(event);\n    this._backdropTransitionendHandler = event => {\n      this._disposeBackdrop(event.target);\n    };\n    /** Stream of keydown events dispatched to this overlay. */\n    this._keydownEvents = new Subject();\n    /** Stream of mouse outside events dispatched to this overlay. */\n    this._outsidePointerEvents = new Subject();\n    if (_config.scrollStrategy) {\n      this._scrollStrategy = _config.scrollStrategy;\n      this._scrollStrategy.attach(this);\n    }\n    this._positionStrategy = _config.positionStrategy;\n  }\n  /** The overlay's HTML element */\n  get overlayElement() {\n    return this._pane;\n  }\n  /** The overlay's backdrop HTML element. */\n  get backdropElement() {\n    return this._backdropElement;\n  }\n  /**\n   * Wrapper around the panel element. Can be used for advanced\n   * positioning where a wrapper with specific styling is\n   * required around the overlay pane.\n   */\n  get hostElement() {\n    return this._host;\n  }\n  /**\n   * Attaches content, given via a Portal, to the overlay.\n   * If the overlay is configured to have a backdrop, it will be created.\n   *\n   * @param portal Portal instance to which to attach the overlay.\n   * @returns The portal attachment result.\n   */\n  attach(portal) {\n    // Insert the host into the DOM before attaching the portal, otherwise\n    // the animations module will skip animations on repeat attachments.\n    if (!this._host.parentElement && this._previousHostParent) {\n      this._previousHostParent.appendChild(this._host);\n    }\n    const attachResult = this._portalOutlet.attach(portal);\n    if (this._positionStrategy) {\n      this._positionStrategy.attach(this);\n    }\n    this._updateStackingOrder();\n    this._updateElementSize();\n    this._updateElementDirection();\n    if (this._scrollStrategy) {\n      this._scrollStrategy.enable();\n    }\n    // Update the position once the zone is stable so that the overlay will be fully rendered\n    // before attempting to position it, as the position may depend on the size of the rendered\n    // content.\n    this._ngZone.onStable.pipe(take(1)).subscribe(() => {\n      // The overlay could've been detached before the zone has stabilized.\n      if (this.hasAttached()) {\n        this.updatePosition();\n      }\n    });\n    // Enable pointer events for the overlay pane element.\n    this._togglePointerEvents(true);\n    if (this._config.hasBackdrop) {\n      this._attachBackdrop();\n    }\n    if (this._config.panelClass) {\n      this._toggleClasses(this._pane, this._config.panelClass, true);\n    }\n    // Only emit the `attachments` event once all other setup is done.\n    this._attachments.next();\n    // Track this overlay by the keyboard dispatcher\n    this._keyboardDispatcher.add(this);\n    if (this._config.disposeOnNavigation) {\n      this._locationChanges = this._location.subscribe(() => this.dispose());\n    }\n    this._outsideClickDispatcher.add(this);\n    // TODO(crisbeto): the null check is here, because the portal outlet returns `any`.\n    // We should be guaranteed for the result to be `ComponentRef | EmbeddedViewRef`, but\n    // `instanceof EmbeddedViewRef` doesn't appear to work at the moment.\n    if (typeof attachResult?.onDestroy === 'function') {\n      // In most cases we control the portal and we know when it is being detached so that\n      // we can finish the disposal process. The exception is if the user passes in a custom\n      // `ViewContainerRef` that isn't destroyed through the overlay API. Note that we use\n      // `detach` here instead of `dispose`, because we don't know if the user intends to\n      // reattach the overlay at a later point. It also has the advantage of waiting for animations.\n      attachResult.onDestroy(() => {\n        if (this.hasAttached()) {\n          // We have to delay the `detach` call, because detaching immediately prevents\n          // other destroy hooks from running. This is likely a framework bug similar to\n          // https://github.com/angular/angular/issues/46119\n          this._ngZone.runOutsideAngular(() => Promise.resolve().then(() => this.detach()));\n        }\n      });\n    }\n    return attachResult;\n  }\n  /**\n   * Detaches an overlay from a portal.\n   * @returns The portal detachment result.\n   */\n  detach() {\n    if (!this.hasAttached()) {\n      return;\n    }\n    this.detachBackdrop();\n    // When the overlay is detached, the pane element should disable pointer events.\n    // This is necessary because otherwise the pane element will cover the page and disable\n    // pointer events therefore. Depends on the position strategy and the applied pane boundaries.\n    this._togglePointerEvents(false);\n    if (this._positionStrategy && this._positionStrategy.detach) {\n      this._positionStrategy.detach();\n    }\n    if (this._scrollStrategy) {\n      this._scrollStrategy.disable();\n    }\n    const detachmentResult = this._portalOutlet.detach();\n    // Only emit after everything is detached.\n    this._detachments.next();\n    // Remove this overlay from keyboard dispatcher tracking.\n    this._keyboardDispatcher.remove(this);\n    // Keeping the host element in the DOM can cause scroll jank, because it still gets\n    // rendered, even though it's transparent and unclickable which is why we remove it.\n    this._detachContentWhenStable();\n    this._locationChanges.unsubscribe();\n    this._outsideClickDispatcher.remove(this);\n    return detachmentResult;\n  }\n  /** Cleans up the overlay from the DOM. */\n  dispose() {\n    const isAttached = this.hasAttached();\n    if (this._positionStrategy) {\n      this._positionStrategy.dispose();\n    }\n    this._disposeScrollStrategy();\n    this._disposeBackdrop(this._backdropElement);\n    this._locationChanges.unsubscribe();\n    this._keyboardDispatcher.remove(this);\n    this._portalOutlet.dispose();\n    this._attachments.complete();\n    this._backdropClick.complete();\n    this._keydownEvents.complete();\n    this._outsidePointerEvents.complete();\n    this._outsideClickDispatcher.remove(this);\n    this._host?.remove();\n    this._previousHostParent = this._pane = this._host = null;\n    if (isAttached) {\n      this._detachments.next();\n    }\n    this._detachments.complete();\n  }\n  /** Whether the overlay has attached content. */\n  hasAttached() {\n    return this._portalOutlet.hasAttached();\n  }\n  /** Gets an observable that emits when the backdrop has been clicked. */\n  backdropClick() {\n    return this._backdropClick;\n  }\n  /** Gets an observable that emits when the overlay has been attached. */\n  attachments() {\n    return this._attachments;\n  }\n  /** Gets an observable that emits when the overlay has been detached. */\n  detachments() {\n    return this._detachments;\n  }\n  /** Gets an observable of keydown events targeted to this overlay. */\n  keydownEvents() {\n    return this._keydownEvents;\n  }\n  /** Gets an observable of pointer events targeted outside this overlay. */\n  outsidePointerEvents() {\n    return this._outsidePointerEvents;\n  }\n  /** Gets the current overlay configuration, which is immutable. */\n  getConfig() {\n    return this._config;\n  }\n  /** Updates the position of the overlay based on the position strategy. */\n  updatePosition() {\n    if (this._positionStrategy) {\n      this._positionStrategy.apply();\n    }\n  }\n  /** Switches to a new position strategy and updates the overlay position. */\n  updatePositionStrategy(strategy) {\n    if (strategy === this._positionStrategy) {\n      return;\n    }\n    if (this._positionStrategy) {\n      this._positionStrategy.dispose();\n    }\n    this._positionStrategy = strategy;\n    if (this.hasAttached()) {\n      strategy.attach(this);\n      this.updatePosition();\n    }\n  }\n  /** Update the size properties of the overlay. */\n  updateSize(sizeConfig) {\n    this._config = {\n      ...this._config,\n      ...sizeConfig\n    };\n    this._updateElementSize();\n  }\n  /** Sets the LTR/RTL direction for the overlay. */\n  setDirection(dir) {\n    this._config = {\n      ...this._config,\n      direction: dir\n    };\n    this._updateElementDirection();\n  }\n  /** Add a CSS class or an array of classes to the overlay pane. */\n  addPanelClass(classes) {\n    if (this._pane) {\n      this._toggleClasses(this._pane, classes, true);\n    }\n  }\n  /** Remove a CSS class or an array of classes from the overlay pane. */\n  removePanelClass(classes) {\n    if (this._pane) {\n      this._toggleClasses(this._pane, classes, false);\n    }\n  }\n  /**\n   * Returns the layout direction of the overlay panel.\n   */\n  getDirection() {\n    const direction = this._config.direction;\n    if (!direction) {\n      return 'ltr';\n    }\n    return typeof direction === 'string' ? direction : direction.value;\n  }\n  /** Switches to a new scroll strategy. */\n  updateScrollStrategy(strategy) {\n    if (strategy === this._scrollStrategy) {\n      return;\n    }\n    this._disposeScrollStrategy();\n    this._scrollStrategy = strategy;\n    if (this.hasAttached()) {\n      strategy.attach(this);\n      strategy.enable();\n    }\n  }\n  /** Updates the text direction of the overlay panel. */\n  _updateElementDirection() {\n    this._host.setAttribute('dir', this.getDirection());\n  }\n  /** Updates the size of the overlay element based on the overlay config. */\n  _updateElementSize() {\n    if (!this._pane) {\n      return;\n    }\n    const style = this._pane.style;\n    style.width = coerceCssPixelValue(this._config.width);\n    style.height = coerceCssPixelValue(this._config.height);\n    style.minWidth = coerceCssPixelValue(this._config.minWidth);\n    style.minHeight = coerceCssPixelValue(this._config.minHeight);\n    style.maxWidth = coerceCssPixelValue(this._config.maxWidth);\n    style.maxHeight = coerceCssPixelValue(this._config.maxHeight);\n  }\n  /** Toggles the pointer events for the overlay pane element. */\n  _togglePointerEvents(enablePointer) {\n    this._pane.style.pointerEvents = enablePointer ? '' : 'none';\n  }\n  /** Attaches a backdrop for this overlay. */\n  _attachBackdrop() {\n    const showingClass = 'cdk-overlay-backdrop-showing';\n    this._backdropElement = this._document.createElement('div');\n    this._backdropElement.classList.add('cdk-overlay-backdrop');\n    if (this._animationsDisabled) {\n      this._backdropElement.classList.add('cdk-overlay-backdrop-noop-animation');\n    }\n    if (this._config.backdropClass) {\n      this._toggleClasses(this._backdropElement, this._config.backdropClass, true);\n    }\n    // Insert the backdrop before the pane in the DOM order,\n    // in order to handle stacked overlays properly.\n    this._host.parentElement.insertBefore(this._backdropElement, this._host);\n    // Forward backdrop clicks such that the consumer of the overlay can perform whatever\n    // action desired when such a click occurs (usually closing the overlay).\n    this._backdropElement.addEventListener('click', this._backdropClickHandler);\n    // Add class to fade-in the backdrop after one frame.\n    if (!this._animationsDisabled && typeof requestAnimationFrame !== 'undefined') {\n      this._ngZone.runOutsideAngular(() => {\n        requestAnimationFrame(() => {\n          if (this._backdropElement) {\n            this._backdropElement.classList.add(showingClass);\n          }\n        });\n      });\n    } else {\n      this._backdropElement.classList.add(showingClass);\n    }\n  }\n  /**\n   * Updates the stacking order of the element, moving it to the top if necessary.\n   * This is required in cases where one overlay was detached, while another one,\n   * that should be behind it, was destroyed. The next time both of them are opened,\n   * the stacking will be wrong, because the detached element's pane will still be\n   * in its original DOM position.\n   */\n  _updateStackingOrder() {\n    if (this._host.nextSibling) {\n      this._host.parentNode.appendChild(this._host);\n    }\n  }\n  /** Detaches the backdrop (if any) associated with the overlay. */\n  detachBackdrop() {\n    const backdropToDetach = this._backdropElement;\n    if (!backdropToDetach) {\n      return;\n    }\n    if (this._animationsDisabled) {\n      this._disposeBackdrop(backdropToDetach);\n      return;\n    }\n    backdropToDetach.classList.remove('cdk-overlay-backdrop-showing');\n    this._ngZone.runOutsideAngular(() => {\n      backdropToDetach.addEventListener('transitionend', this._backdropTransitionendHandler);\n    });\n    // If the backdrop doesn't have a transition, the `transitionend` event won't fire.\n    // In this case we make it unclickable and we try to remove it after a delay.\n    backdropToDetach.style.pointerEvents = 'none';\n    // Run this outside the Angular zone because there's nothing that Angular cares about.\n    // If it were to run inside the Angular zone, every test that used Overlay would have to be\n    // either async or fakeAsync.\n    this._backdropTimeout = this._ngZone.runOutsideAngular(() => setTimeout(() => {\n      this._disposeBackdrop(backdropToDetach);\n    }, 500));\n  }\n  /** Toggles a single CSS class or an array of classes on an element. */\n  _toggleClasses(element, cssClasses, isAdd) {\n    const classes = coerceArray(cssClasses || []).filter(c => !!c);\n    if (classes.length) {\n      isAdd ? element.classList.add(...classes) : element.classList.remove(...classes);\n    }\n  }\n  /** Detaches the overlay content next time the zone stabilizes. */\n  _detachContentWhenStable() {\n    // Normally we wouldn't have to explicitly run this outside the `NgZone`, however\n    // if the consumer is using `zone-patch-rxjs`, the `Subscription.unsubscribe` call will\n    // be patched to run inside the zone, which will throw us into an infinite loop.\n    this._ngZone.runOutsideAngular(() => {\n      // We can't remove the host here immediately, because the overlay pane's content\n      // might still be animating. This stream helps us avoid interrupting the animation\n      // by waiting for the pane to become empty.\n      const subscription = this._ngZone.onStable.pipe(takeUntil(merge(this._attachments, this._detachments))).subscribe(() => {\n        // Needs a couple of checks for the pane and host, because\n        // they may have been removed by the time the zone stabilizes.\n        if (!this._pane || !this._host || this._pane.children.length === 0) {\n          if (this._pane && this._config.panelClass) {\n            this._toggleClasses(this._pane, this._config.panelClass, false);\n          }\n          if (this._host && this._host.parentElement) {\n            this._previousHostParent = this._host.parentElement;\n            this._host.remove();\n          }\n          subscription.unsubscribe();\n        }\n      });\n    });\n  }\n  /** Disposes of a scroll strategy. */\n  _disposeScrollStrategy() {\n    const scrollStrategy = this._scrollStrategy;\n    if (scrollStrategy) {\n      scrollStrategy.disable();\n      if (scrollStrategy.detach) {\n        scrollStrategy.detach();\n      }\n    }\n  }\n  /** Removes a backdrop element from the DOM. */\n  _disposeBackdrop(backdrop) {\n    if (backdrop) {\n      backdrop.removeEventListener('click', this._backdropClickHandler);\n      backdrop.removeEventListener('transitionend', this._backdropTransitionendHandler);\n      backdrop.remove();\n      // It is possible that a new portal has been attached to this overlay since we started\n      // removing the backdrop. If that is the case, only clear the backdrop reference if it\n      // is still the same instance that we started to remove.\n      if (this._backdropElement === backdrop) {\n        this._backdropElement = null;\n      }\n    }\n    if (this._backdropTimeout) {\n      clearTimeout(this._backdropTimeout);\n      this._backdropTimeout = undefined;\n    }\n  }\n}\n\n// TODO: refactor clipping detection into a separate thing (part of scrolling module)\n// TODO: doesn't handle both flexible width and height when it has to scroll along both axis.\n/** Class to be added to the overlay bounding box. */\nconst boundingBoxClass = 'cdk-overlay-connected-position-bounding-box';\n/** Regex used to split a string on its CSS units. */\nconst cssUnitPattern = /([A-Za-z%]+)$/;\n/**\n * A strategy for positioning overlays. Using this strategy, an overlay is given an\n * implicit position relative some origin element. The relative position is defined in terms of\n * a point on the origin element that is connected to a point on the overlay element. For example,\n * a basic dropdown is connecting the bottom-left corner of the origin to the top-left corner\n * of the overlay.\n */\nclass FlexibleConnectedPositionStrategy {\n  /** Ordered list of preferred positions, from most to least desirable. */\n  get positions() {\n    return this._preferredPositions;\n  }\n  constructor(connectedTo, _viewportRuler, _document, _platform, _overlayContainer) {\n    this._viewportRuler = _viewportRuler;\n    this._document = _document;\n    this._platform = _platform;\n    this._overlayContainer = _overlayContainer;\n    /** Last size used for the bounding box. Used to avoid resizing the overlay after open. */\n    this._lastBoundingBoxSize = {\n      width: 0,\n      height: 0\n    };\n    /** Whether the overlay was pushed in a previous positioning. */\n    this._isPushed = false;\n    /** Whether the overlay can be pushed on-screen on the initial open. */\n    this._canPush = true;\n    /** Whether the overlay can grow via flexible width/height after the initial open. */\n    this._growAfterOpen = false;\n    /** Whether the overlay's width and height can be constrained to fit within the viewport. */\n    this._hasFlexibleDimensions = true;\n    /** Whether the overlay position is locked. */\n    this._positionLocked = false;\n    /** Amount of space that must be maintained between the overlay and the edge of the viewport. */\n    this._viewportMargin = 0;\n    /** The Scrollable containers used to check scrollable view properties on position change. */\n    this._scrollables = [];\n    /** Ordered list of preferred positions, from most to least desirable. */\n    this._preferredPositions = [];\n    /** Subject that emits whenever the position changes. */\n    this._positionChanges = new Subject();\n    /** Subscription to viewport size changes. */\n    this._resizeSubscription = Subscription.EMPTY;\n    /** Default offset for the overlay along the x axis. */\n    this._offsetX = 0;\n    /** Default offset for the overlay along the y axis. */\n    this._offsetY = 0;\n    /** Keeps track of the CSS classes that the position strategy has applied on the overlay panel. */\n    this._appliedPanelClasses = [];\n    /** Observable sequence of position changes. */\n    this.positionChanges = this._positionChanges;\n    this.setOrigin(connectedTo);\n  }\n  /** Attaches this position strategy to an overlay. */\n  attach(overlayRef) {\n    if (this._overlayRef && overlayRef !== this._overlayRef && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n      throw Error('This position strategy is already attached to an overlay');\n    }\n    this._validatePositions();\n    overlayRef.hostElement.classList.add(boundingBoxClass);\n    this._overlayRef = overlayRef;\n    this._boundingBox = overlayRef.hostElement;\n    this._pane = overlayRef.overlayElement;\n    this._isDisposed = false;\n    this._isInitialRender = true;\n    this._lastPosition = null;\n    this._resizeSubscription.unsubscribe();\n    this._resizeSubscription = this._viewportRuler.change().subscribe(() => {\n      // When the window is resized, we want to trigger the next reposition as if it\n      // was an initial render, in order for the strategy to pick a new optimal position,\n      // otherwise position locking will cause it to stay at the old one.\n      this._isInitialRender = true;\n      this.apply();\n    });\n  }\n  /**\n   * Updates the position of the overlay element, using whichever preferred position relative\n   * to the origin best fits on-screen.\n   *\n   * The selection of a position goes as follows:\n   *  - If any positions fit completely within the viewport as-is,\n   *      choose the first position that does so.\n   *  - If flexible dimensions are enabled and at least one satisfies the given minimum width/height,\n   *      choose the position with the greatest available size modified by the positions' weight.\n   *  - If pushing is enabled, take the position that went off-screen the least and push it\n   *      on-screen.\n   *  - If none of the previous criteria were met, use the position that goes off-screen the least.\n   * @docs-private\n   */\n  apply() {\n    // We shouldn't do anything if the strategy was disposed or we're on the server.\n    if (this._isDisposed || !this._platform.isBrowser) {\n      return;\n    }\n    // If the position has been applied already (e.g. when the overlay was opened) and the\n    // consumer opted into locking in the position, re-use the old position, in order to\n    // prevent the overlay from jumping around.\n    if (!this._isInitialRender && this._positionLocked && this._lastPosition) {\n      this.reapplyLastPosition();\n      return;\n    }\n    this._clearPanelClasses();\n    this._resetOverlayElementStyles();\n    this._resetBoundingBoxStyles();\n    // We need the bounding rects for the origin, the overlay and the container to determine how to position\n    // the overlay relative to the origin.\n    // We use the viewport rect to determine whether a position would go off-screen.\n    this._viewportRect = this._getNarrowedViewportRect();\n    this._originRect = this._getOriginRect();\n    this._overlayRect = this._pane.getBoundingClientRect();\n    this._containerRect = this._overlayContainer.getContainerElement().getBoundingClientRect();\n    const originRect = this._originRect;\n    const overlayRect = this._overlayRect;\n    const viewportRect = this._viewportRect;\n    const containerRect = this._containerRect;\n    // Positions where the overlay will fit with flexible dimensions.\n    const flexibleFits = [];\n    // Fallback if none of the preferred positions fit within the viewport.\n    let fallback;\n    // Go through each of the preferred positions looking for a good fit.\n    // If a good fit is found, it will be applied immediately.\n    for (let pos of this._preferredPositions) {\n      // Get the exact (x, y) coordinate for the point-of-origin on the origin element.\n      let originPoint = this._getOriginPoint(originRect, containerRect, pos);\n      // From that point-of-origin, get the exact (x, y) coordinate for the top-left corner of the\n      // overlay in this position. We use the top-left corner for calculations and later translate\n      // this into an appropriate (top, left, bottom, right) style.\n      let overlayPoint = this._getOverlayPoint(originPoint, overlayRect, pos);\n      // Calculate how well the overlay would fit into the viewport with this point.\n      let overlayFit = this._getOverlayFit(overlayPoint, overlayRect, viewportRect, pos);\n      // If the overlay, without any further work, fits into the viewport, use this position.\n      if (overlayFit.isCompletelyWithinViewport) {\n        this._isPushed = false;\n        this._applyPosition(pos, originPoint);\n        return;\n      }\n      // If the overlay has flexible dimensions, we can use this position\n      // so long as there's enough space for the minimum dimensions.\n      if (this._canFitWithFlexibleDimensions(overlayFit, overlayPoint, viewportRect)) {\n        // Save positions where the overlay will fit with flexible dimensions. We will use these\n        // if none of the positions fit *without* flexible dimensions.\n        flexibleFits.push({\n          position: pos,\n          origin: originPoint,\n          overlayRect,\n          boundingBoxRect: this._calculateBoundingBoxRect(originPoint, pos)\n        });\n        continue;\n      }\n      // If the current preferred position does not fit on the screen, remember the position\n      // if it has more visible area on-screen than we've seen and move onto the next preferred\n      // position.\n      if (!fallback || fallback.overlayFit.visibleArea < overlayFit.visibleArea) {\n        fallback = {\n          overlayFit,\n          overlayPoint,\n          originPoint,\n          position: pos,\n          overlayRect\n        };\n      }\n    }\n    // If there are any positions where the overlay would fit with flexible dimensions, choose the\n    // one that has the greatest area available modified by the position's weight\n    if (flexibleFits.length) {\n      let bestFit = null;\n      let bestScore = -1;\n      for (const fit of flexibleFits) {\n        const score = fit.boundingBoxRect.width * fit.boundingBoxRect.height * (fit.position.weight || 1);\n        if (score > bestScore) {\n          bestScore = score;\n          bestFit = fit;\n        }\n      }\n      this._isPushed = false;\n      this._applyPosition(bestFit.position, bestFit.origin);\n      return;\n    }\n    // When none of the preferred positions fit within the viewport, take the position\n    // that went off-screen the least and attempt to push it on-screen.\n    if (this._canPush) {\n      // TODO(jelbourn): after pushing, the opening \"direction\" of the overlay might not make sense.\n      this._isPushed = true;\n      this._applyPosition(fallback.position, fallback.originPoint);\n      return;\n    }\n    // All options for getting the overlay within the viewport have been exhausted, so go with the\n    // position that went off-screen the least.\n    this._applyPosition(fallback.position, fallback.originPoint);\n  }\n  detach() {\n    this._clearPanelClasses();\n    this._lastPosition = null;\n    this._previousPushAmount = null;\n    this._resizeSubscription.unsubscribe();\n  }\n  /** Cleanup after the element gets destroyed. */\n  dispose() {\n    if (this._isDisposed) {\n      return;\n    }\n    // We can't use `_resetBoundingBoxStyles` here, because it resets\n    // some properties to zero, rather than removing them.\n    if (this._boundingBox) {\n      extendStyles(this._boundingBox.style, {\n        top: '',\n        left: '',\n        right: '',\n        bottom: '',\n        height: '',\n        width: '',\n        alignItems: '',\n        justifyContent: ''\n      });\n    }\n    if (this._pane) {\n      this._resetOverlayElementStyles();\n    }\n    if (this._overlayRef) {\n      this._overlayRef.hostElement.classList.remove(boundingBoxClass);\n    }\n    this.detach();\n    this._positionChanges.complete();\n    this._overlayRef = this._boundingBox = null;\n    this._isDisposed = true;\n  }\n  /**\n   * This re-aligns the overlay element with the trigger in its last calculated position,\n   * even if a position higher in the \"preferred positions\" list would now fit. This\n   * allows one to re-align the panel without changing the orientation of the panel.\n   */\n  reapplyLastPosition() {\n    if (this._isDisposed || !this._platform.isBrowser) {\n      return;\n    }\n    const lastPosition = this._lastPosition;\n    if (lastPosition) {\n      this._originRect = this._getOriginRect();\n      this._overlayRect = this._pane.getBoundingClientRect();\n      this._viewportRect = this._getNarrowedViewportRect();\n      this._containerRect = this._overlayContainer.getContainerElement().getBoundingClientRect();\n      const originPoint = this._getOriginPoint(this._originRect, this._containerRect, lastPosition);\n      this._applyPosition(lastPosition, originPoint);\n    } else {\n      this.apply();\n    }\n  }\n  /**\n   * Sets the list of Scrollable containers that host the origin element so that\n   * on reposition we can evaluate if it or the overlay has been clipped or outside view. Every\n   * Scrollable must be an ancestor element of the strategy's origin element.\n   */\n  withScrollableContainers(scrollables) {\n    this._scrollables = scrollables;\n    return this;\n  }\n  /**\n   * Adds new preferred positions.\n   * @param positions List of positions options for this overlay.\n   */\n  withPositions(positions) {\n    this._preferredPositions = positions;\n    // If the last calculated position object isn't part of the positions anymore, clear\n    // it in order to avoid it being picked up if the consumer tries to re-apply.\n    if (positions.indexOf(this._lastPosition) === -1) {\n      this._lastPosition = null;\n    }\n    this._validatePositions();\n    return this;\n  }\n  /**\n   * Sets a minimum distance the overlay may be positioned to the edge of the viewport.\n   * @param margin Required margin between the overlay and the viewport edge in pixels.\n   */\n  withViewportMargin(margin) {\n    this._viewportMargin = margin;\n    return this;\n  }\n  /** Sets whether the overlay's width and height can be constrained to fit within the viewport. */\n  withFlexibleDimensions(flexibleDimensions = true) {\n    this._hasFlexibleDimensions = flexibleDimensions;\n    return this;\n  }\n  /** Sets whether the overlay can grow after the initial open via flexible width/height. */\n  withGrowAfterOpen(growAfterOpen = true) {\n    this._growAfterOpen = growAfterOpen;\n    return this;\n  }\n  /** Sets whether the overlay can be pushed on-screen if none of the provided positions fit. */\n  withPush(canPush = true) {\n    this._canPush = canPush;\n    return this;\n  }\n  /**\n   * Sets whether the overlay's position should be locked in after it is positioned\n   * initially. When an overlay is locked in, it won't attempt to reposition itself\n   * when the position is re-applied (e.g. when the user scrolls away).\n   * @param isLocked Whether the overlay should locked in.\n   */\n  withLockedPosition(isLocked = true) {\n    this._positionLocked = isLocked;\n    return this;\n  }\n  /**\n   * Sets the origin, relative to which to position the overlay.\n   * Using an element origin is useful for building components that need to be positioned\n   * relatively to a trigger (e.g. dropdown menus or tooltips), whereas using a point can be\n   * used for cases like contextual menus which open relative to the user's pointer.\n   * @param origin Reference to the new origin.\n   */\n  setOrigin(origin) {\n    this._origin = origin;\n    return this;\n  }\n  /**\n   * Sets the default offset for the overlay's connection point on the x-axis.\n   * @param offset New offset in the X axis.\n   */\n  withDefaultOffsetX(offset) {\n    this._offsetX = offset;\n    return this;\n  }\n  /**\n   * Sets the default offset for the overlay's connection point on the y-axis.\n   * @param offset New offset in the Y axis.\n   */\n  withDefaultOffsetY(offset) {\n    this._offsetY = offset;\n    return this;\n  }\n  /**\n   * Configures that the position strategy should set a `transform-origin` on some elements\n   * inside the overlay, depending on the current position that is being applied. This is\n   * useful for the cases where the origin of an animation can change depending on the\n   * alignment of the overlay.\n   * @param selector CSS selector that will be used to find the target\n   *    elements onto which to set the transform origin.\n   */\n  withTransformOriginOn(selector) {\n    this._transformOriginSelector = selector;\n    return this;\n  }\n  /**\n   * Gets the (x, y) coordinate of a connection point on the origin based on a relative position.\n   */\n  _getOriginPoint(originRect, containerRect, pos) {\n    let x;\n    if (pos.originX == 'center') {\n      // Note: when centering we should always use the `left`\n      // offset, otherwise the position will be wrong in RTL.\n      x = originRect.left + originRect.width / 2;\n    } else {\n      const startX = this._isRtl() ? originRect.right : originRect.left;\n      const endX = this._isRtl() ? originRect.left : originRect.right;\n      x = pos.originX == 'start' ? startX : endX;\n    }\n    // When zooming in Safari the container rectangle contains negative values for the position\n    // and we need to re-add them to the calculated coordinates.\n    if (containerRect.left < 0) {\n      x -= containerRect.left;\n    }\n    let y;\n    if (pos.originY == 'center') {\n      y = originRect.top + originRect.height / 2;\n    } else {\n      y = pos.originY == 'top' ? originRect.top : originRect.bottom;\n    }\n    // Normally the containerRect's top value would be zero, however when the overlay is attached to an input\n    // (e.g. in an autocomplete), mobile browsers will shift everything in order to put the input in the middle\n    // of the screen and to make space for the virtual keyboard. We need to account for this offset,\n    // otherwise our positioning will be thrown off.\n    // Additionally, when zooming in Safari this fixes the vertical position.\n    if (containerRect.top < 0) {\n      y -= containerRect.top;\n    }\n    return {\n      x,\n      y\n    };\n  }\n  /**\n   * Gets the (x, y) coordinate of the top-left corner of the overlay given a given position and\n   * origin point to which the overlay should be connected.\n   */\n  _getOverlayPoint(originPoint, overlayRect, pos) {\n    // Calculate the (overlayStartX, overlayStartY), the start of the\n    // potential overlay position relative to the origin point.\n    let overlayStartX;\n    if (pos.overlayX == 'center') {\n      overlayStartX = -overlayRect.width / 2;\n    } else if (pos.overlayX === 'start') {\n      overlayStartX = this._isRtl() ? -overlayRect.width : 0;\n    } else {\n      overlayStartX = this._isRtl() ? 0 : -overlayRect.width;\n    }\n    let overlayStartY;\n    if (pos.overlayY == 'center') {\n      overlayStartY = -overlayRect.height / 2;\n    } else {\n      overlayStartY = pos.overlayY == 'top' ? 0 : -overlayRect.height;\n    }\n    // The (x, y) coordinates of the overlay.\n    return {\n      x: originPoint.x + overlayStartX,\n      y: originPoint.y + overlayStartY\n    };\n  }\n  /** Gets how well an overlay at the given point will fit within the viewport. */\n  _getOverlayFit(point, rawOverlayRect, viewport, position) {\n    // Round the overlay rect when comparing against the\n    // viewport, because the viewport is always rounded.\n    const overlay = getRoundedBoundingClientRect(rawOverlayRect);\n    let {\n      x,\n      y\n    } = point;\n    let offsetX = this._getOffset(position, 'x');\n    let offsetY = this._getOffset(position, 'y');\n    // Account for the offsets since they could push the overlay out of the viewport.\n    if (offsetX) {\n      x += offsetX;\n    }\n    if (offsetY) {\n      y += offsetY;\n    }\n    // How much the overlay would overflow at this position, on each side.\n    let leftOverflow = 0 - x;\n    let rightOverflow = x + overlay.width - viewport.width;\n    let topOverflow = 0 - y;\n    let bottomOverflow = y + overlay.height - viewport.height;\n    // Visible parts of the element on each axis.\n    let visibleWidth = this._subtractOverflows(overlay.width, leftOverflow, rightOverflow);\n    let visibleHeight = this._subtractOverflows(overlay.height, topOverflow, bottomOverflow);\n    let visibleArea = visibleWidth * visibleHeight;\n    return {\n      visibleArea,\n      isCompletelyWithinViewport: overlay.width * overlay.height === visibleArea,\n      fitsInViewportVertically: visibleHeight === overlay.height,\n      fitsInViewportHorizontally: visibleWidth == overlay.width\n    };\n  }\n  /**\n   * Whether the overlay can fit within the viewport when it may resize either its width or height.\n   * @param fit How well the overlay fits in the viewport at some position.\n   * @param point The (x, y) coordinates of the overlay at some position.\n   * @param viewport The geometry of the viewport.\n   */\n  _canFitWithFlexibleDimensions(fit, point, viewport) {\n    if (this._hasFlexibleDimensions) {\n      const availableHeight = viewport.bottom - point.y;\n      const availableWidth = viewport.right - point.x;\n      const minHeight = getPixelValue(this._overlayRef.getConfig().minHeight);\n      const minWidth = getPixelValue(this._overlayRef.getConfig().minWidth);\n      const verticalFit = fit.fitsInViewportVertically || minHeight != null && minHeight <= availableHeight;\n      const horizontalFit = fit.fitsInViewportHorizontally || minWidth != null && minWidth <= availableWidth;\n      return verticalFit && horizontalFit;\n    }\n    return false;\n  }\n  /**\n   * Gets the point at which the overlay can be \"pushed\" on-screen. If the overlay is larger than\n   * the viewport, the top-left corner will be pushed on-screen (with overflow occurring on the\n   * right and bottom).\n   *\n   * @param start Starting point from which the overlay is pushed.\n   * @param rawOverlayRect Dimensions of the overlay.\n   * @param scrollPosition Current viewport scroll position.\n   * @returns The point at which to position the overlay after pushing. This is effectively a new\n   *     originPoint.\n   */\n  _pushOverlayOnScreen(start, rawOverlayRect, scrollPosition) {\n    // If the position is locked and we've pushed the overlay already, reuse the previous push\n    // amount, rather than pushing it again. If we were to continue pushing, the element would\n    // remain in the viewport, which goes against the expectations when position locking is enabled.\n    if (this._previousPushAmount && this._positionLocked) {\n      return {\n        x: start.x + this._previousPushAmount.x,\n        y: start.y + this._previousPushAmount.y\n      };\n    }\n    // Round the overlay rect when comparing against the\n    // viewport, because the viewport is always rounded.\n    const overlay = getRoundedBoundingClientRect(rawOverlayRect);\n    const viewport = this._viewportRect;\n    // Determine how much the overlay goes outside the viewport on each\n    // side, which we'll use to decide which direction to push it.\n    const overflowRight = Math.max(start.x + overlay.width - viewport.width, 0);\n    const overflowBottom = Math.max(start.y + overlay.height - viewport.height, 0);\n    const overflowTop = Math.max(viewport.top - scrollPosition.top - start.y, 0);\n    const overflowLeft = Math.max(viewport.left - scrollPosition.left - start.x, 0);\n    // Amount by which to push the overlay in each axis such that it remains on-screen.\n    let pushX = 0;\n    let pushY = 0;\n    // If the overlay fits completely within the bounds of the viewport, push it from whichever\n    // direction is goes off-screen. Otherwise, push the top-left corner such that its in the\n    // viewport and allow for the trailing end of the overlay to go out of bounds.\n    if (overlay.width <= viewport.width) {\n      pushX = overflowLeft || -overflowRight;\n    } else {\n      pushX = start.x < this._viewportMargin ? viewport.left - scrollPosition.left - start.x : 0;\n    }\n    if (overlay.height <= viewport.height) {\n      pushY = overflowTop || -overflowBottom;\n    } else {\n      pushY = start.y < this._viewportMargin ? viewport.top - scrollPosition.top - start.y : 0;\n    }\n    this._previousPushAmount = {\n      x: pushX,\n      y: pushY\n    };\n    return {\n      x: start.x + pushX,\n      y: start.y + pushY\n    };\n  }\n  /**\n   * Applies a computed position to the overlay and emits a position change.\n   * @param position The position preference\n   * @param originPoint The point on the origin element where the overlay is connected.\n   */\n  _applyPosition(position, originPoint) {\n    this._setTransformOrigin(position);\n    this._setOverlayElementStyles(originPoint, position);\n    this._setBoundingBoxStyles(originPoint, position);\n    if (position.panelClass) {\n      this._addPanelClasses(position.panelClass);\n    }\n    // Notify that the position has been changed along with its change properties.\n    // We only emit if we've got any subscriptions, because the scroll visibility\n    // calculations can be somewhat expensive.\n    if (this._positionChanges.observers.length) {\n      const scrollVisibility = this._getScrollVisibility();\n      // We're recalculating on scroll, but we only want to emit if anything\n      // changed since downstream code might be hitting the `NgZone`.\n      if (position !== this._lastPosition || !this._lastScrollVisibility || !compareScrollVisibility(this._lastScrollVisibility, scrollVisibility)) {\n        const changeEvent = new ConnectedOverlayPositionChange(position, scrollVisibility);\n        this._positionChanges.next(changeEvent);\n      }\n      this._lastScrollVisibility = scrollVisibility;\n    }\n    // Save the last connected position in case the position needs to be re-calculated.\n    this._lastPosition = position;\n    this._isInitialRender = false;\n  }\n  /** Sets the transform origin based on the configured selector and the passed-in position.  */\n  _setTransformOrigin(position) {\n    if (!this._transformOriginSelector) {\n      return;\n    }\n    const elements = this._boundingBox.querySelectorAll(this._transformOriginSelector);\n    let xOrigin;\n    let yOrigin = position.overlayY;\n    if (position.overlayX === 'center') {\n      xOrigin = 'center';\n    } else if (this._isRtl()) {\n      xOrigin = position.overlayX === 'start' ? 'right' : 'left';\n    } else {\n      xOrigin = position.overlayX === 'start' ? 'left' : 'right';\n    }\n    for (let i = 0; i < elements.length; i++) {\n      elements[i].style.transformOrigin = `${xOrigin} ${yOrigin}`;\n    }\n  }\n  /**\n   * Gets the position and size of the overlay's sizing container.\n   *\n   * This method does no measuring and applies no styles so that we can cheaply compute the\n   * bounds for all positions and choose the best fit based on these results.\n   */\n  _calculateBoundingBoxRect(origin, position) {\n    const viewport = this._viewportRect;\n    const isRtl = this._isRtl();\n    let height, top, bottom;\n    if (position.overlayY === 'top') {\n      // Overlay is opening \"downward\" and thus is bound by the bottom viewport edge.\n      top = origin.y;\n      height = viewport.height - top + this._viewportMargin;\n    } else if (position.overlayY === 'bottom') {\n      // Overlay is opening \"upward\" and thus is bound by the top viewport edge. We need to add\n      // the viewport margin back in, because the viewport rect is narrowed down to remove the\n      // margin, whereas the `origin` position is calculated based on its `DOMRect`.\n      bottom = viewport.height - origin.y + this._viewportMargin * 2;\n      height = viewport.height - bottom + this._viewportMargin;\n    } else {\n      // If neither top nor bottom, it means that the overlay is vertically centered on the\n      // origin point. Note that we want the position relative to the viewport, rather than\n      // the page, which is why we don't use something like `viewport.bottom - origin.y` and\n      // `origin.y - viewport.top`.\n      const smallestDistanceToViewportEdge = Math.min(viewport.bottom - origin.y + viewport.top, origin.y);\n      const previousHeight = this._lastBoundingBoxSize.height;\n      height = smallestDistanceToViewportEdge * 2;\n      top = origin.y - smallestDistanceToViewportEdge;\n      if (height > previousHeight && !this._isInitialRender && !this._growAfterOpen) {\n        top = origin.y - previousHeight / 2;\n      }\n    }\n    // The overlay is opening 'right-ward' (the content flows to the right).\n    const isBoundedByRightViewportEdge = position.overlayX === 'start' && !isRtl || position.overlayX === 'end' && isRtl;\n    // The overlay is opening 'left-ward' (the content flows to the left).\n    const isBoundedByLeftViewportEdge = position.overlayX === 'end' && !isRtl || position.overlayX === 'start' && isRtl;\n    let width, left, right;\n    if (isBoundedByLeftViewportEdge) {\n      right = viewport.width - origin.x + this._viewportMargin * 2;\n      width = origin.x - this._viewportMargin;\n    } else if (isBoundedByRightViewportEdge) {\n      left = origin.x;\n      width = viewport.right - origin.x;\n    } else {\n      // If neither start nor end, it means that the overlay is horizontally centered on the\n      // origin point. Note that we want the position relative to the viewport, rather than\n      // the page, which is why we don't use something like `viewport.right - origin.x` and\n      // `origin.x - viewport.left`.\n      const smallestDistanceToViewportEdge = Math.min(viewport.right - origin.x + viewport.left, origin.x);\n      const previousWidth = this._lastBoundingBoxSize.width;\n      width = smallestDistanceToViewportEdge * 2;\n      left = origin.x - smallestDistanceToViewportEdge;\n      if (width > previousWidth && !this._isInitialRender && !this._growAfterOpen) {\n        left = origin.x - previousWidth / 2;\n      }\n    }\n    return {\n      top: top,\n      left: left,\n      bottom: bottom,\n      right: right,\n      width,\n      height\n    };\n  }\n  /**\n   * Sets the position and size of the overlay's sizing wrapper. The wrapper is positioned on the\n   * origin's connection point and stretches to the bounds of the viewport.\n   *\n   * @param origin The point on the origin element where the overlay is connected.\n   * @param position The position preference\n   */\n  _setBoundingBoxStyles(origin, position) {\n    const boundingBoxRect = this._calculateBoundingBoxRect(origin, position);\n    // It's weird if the overlay *grows* while scrolling, so we take the last size into account\n    // when applying a new size.\n    if (!this._isInitialRender && !this._growAfterOpen) {\n      boundingBoxRect.height = Math.min(boundingBoxRect.height, this._lastBoundingBoxSize.height);\n      boundingBoxRect.width = Math.min(boundingBoxRect.width, this._lastBoundingBoxSize.width);\n    }\n    const styles = {};\n    if (this._hasExactPosition()) {\n      styles.top = styles.left = '0';\n      styles.bottom = styles.right = styles.maxHeight = styles.maxWidth = '';\n      styles.width = styles.height = '100%';\n    } else {\n      const maxHeight = this._overlayRef.getConfig().maxHeight;\n      const maxWidth = this._overlayRef.getConfig().maxWidth;\n      styles.height = coerceCssPixelValue(boundingBoxRect.height);\n      styles.top = coerceCssPixelValue(boundingBoxRect.top);\n      styles.bottom = coerceCssPixelValue(boundingBoxRect.bottom);\n      styles.width = coerceCssPixelValue(boundingBoxRect.width);\n      styles.left = coerceCssPixelValue(boundingBoxRect.left);\n      styles.right = coerceCssPixelValue(boundingBoxRect.right);\n      // Push the pane content towards the proper direction.\n      if (position.overlayX === 'center') {\n        styles.alignItems = 'center';\n      } else {\n        styles.alignItems = position.overlayX === 'end' ? 'flex-end' : 'flex-start';\n      }\n      if (position.overlayY === 'center') {\n        styles.justifyContent = 'center';\n      } else {\n        styles.justifyContent = position.overlayY === 'bottom' ? 'flex-end' : 'flex-start';\n      }\n      if (maxHeight) {\n        styles.maxHeight = coerceCssPixelValue(maxHeight);\n      }\n      if (maxWidth) {\n        styles.maxWidth = coerceCssPixelValue(maxWidth);\n      }\n    }\n    this._lastBoundingBoxSize = boundingBoxRect;\n    extendStyles(this._boundingBox.style, styles);\n  }\n  /** Resets the styles for the bounding box so that a new positioning can be computed. */\n  _resetBoundingBoxStyles() {\n    extendStyles(this._boundingBox.style, {\n      top: '0',\n      left: '0',\n      right: '0',\n      bottom: '0',\n      height: '',\n      width: '',\n      alignItems: '',\n      justifyContent: ''\n    });\n  }\n  /** Resets the styles for the overlay pane so that a new positioning can be computed. */\n  _resetOverlayElementStyles() {\n    extendStyles(this._pane.style, {\n      top: '',\n      left: '',\n      bottom: '',\n      right: '',\n      position: '',\n      transform: ''\n    });\n  }\n  /** Sets positioning styles to the overlay element. */\n  _setOverlayElementStyles(originPoint, position) {\n    const styles = {};\n    const hasExactPosition = this._hasExactPosition();\n    const hasFlexibleDimensions = this._hasFlexibleDimensions;\n    const config = this._overlayRef.getConfig();\n    if (hasExactPosition) {\n      const scrollPosition = this._viewportRuler.getViewportScrollPosition();\n      extendStyles(styles, this._getExactOverlayY(position, originPoint, scrollPosition));\n      extendStyles(styles, this._getExactOverlayX(position, originPoint, scrollPosition));\n    } else {\n      styles.position = 'static';\n    }\n    // Use a transform to apply the offsets. We do this because the `center` positions rely on\n    // being in the normal flex flow and setting a `top` / `left` at all will completely throw\n    // off the position. We also can't use margins, because they won't have an effect in some\n    // cases where the element doesn't have anything to \"push off of\". Finally, this works\n    // better both with flexible and non-flexible positioning.\n    let transformString = '';\n    let offsetX = this._getOffset(position, 'x');\n    let offsetY = this._getOffset(position, 'y');\n    if (offsetX) {\n      transformString += `translateX(${offsetX}px) `;\n    }\n    if (offsetY) {\n      transformString += `translateY(${offsetY}px)`;\n    }\n    styles.transform = transformString.trim();\n    // If a maxWidth or maxHeight is specified on the overlay, we remove them. We do this because\n    // we need these values to both be set to \"100%\" for the automatic flexible sizing to work.\n    // The maxHeight and maxWidth are set on the boundingBox in order to enforce the constraint.\n    // Note that this doesn't apply when we have an exact position, in which case we do want to\n    // apply them because they'll be cleared from the bounding box.\n    if (config.maxHeight) {\n      if (hasExactPosition) {\n        styles.maxHeight = coerceCssPixelValue(config.maxHeight);\n      } else if (hasFlexibleDimensions) {\n        styles.maxHeight = '';\n      }\n    }\n    if (config.maxWidth) {\n      if (hasExactPosition) {\n        styles.maxWidth = coerceCssPixelValue(config.maxWidth);\n      } else if (hasFlexibleDimensions) {\n        styles.maxWidth = '';\n      }\n    }\n    extendStyles(this._pane.style, styles);\n  }\n  /** Gets the exact top/bottom for the overlay when not using flexible sizing or when pushing. */\n  _getExactOverlayY(position, originPoint, scrollPosition) {\n    // Reset any existing styles. This is necessary in case the\n    // preferred position has changed since the last `apply`.\n    let styles = {\n      top: '',\n      bottom: ''\n    };\n    let overlayPoint = this._getOverlayPoint(originPoint, this._overlayRect, position);\n    if (this._isPushed) {\n      overlayPoint = this._pushOverlayOnScreen(overlayPoint, this._overlayRect, scrollPosition);\n    }\n    // We want to set either `top` or `bottom` based on whether the overlay wants to appear\n    // above or below the origin and the direction in which the element will expand.\n    if (position.overlayY === 'bottom') {\n      // When using `bottom`, we adjust the y position such that it is the distance\n      // from the bottom of the viewport rather than the top.\n      const documentHeight = this._document.documentElement.clientHeight;\n      styles.bottom = `${documentHeight - (overlayPoint.y + this._overlayRect.height)}px`;\n    } else {\n      styles.top = coerceCssPixelValue(overlayPoint.y);\n    }\n    return styles;\n  }\n  /** Gets the exact left/right for the overlay when not using flexible sizing or when pushing. */\n  _getExactOverlayX(position, originPoint, scrollPosition) {\n    // Reset any existing styles. This is necessary in case the preferred position has\n    // changed since the last `apply`.\n    let styles = {\n      left: '',\n      right: ''\n    };\n    let overlayPoint = this._getOverlayPoint(originPoint, this._overlayRect, position);\n    if (this._isPushed) {\n      overlayPoint = this._pushOverlayOnScreen(overlayPoint, this._overlayRect, scrollPosition);\n    }\n    // We want to set either `left` or `right` based on whether the overlay wants to appear \"before\"\n    // or \"after\" the origin, which determines the direction in which the element will expand.\n    // For the horizontal axis, the meaning of \"before\" and \"after\" change based on whether the\n    // page is in RTL or LTR.\n    let horizontalStyleProperty;\n    if (this._isRtl()) {\n      horizontalStyleProperty = position.overlayX === 'end' ? 'left' : 'right';\n    } else {\n      horizontalStyleProperty = position.overlayX === 'end' ? 'right' : 'left';\n    }\n    // When we're setting `right`, we adjust the x position such that it is the distance\n    // from the right edge of the viewport rather than the left edge.\n    if (horizontalStyleProperty === 'right') {\n      const documentWidth = this._document.documentElement.clientWidth;\n      styles.right = `${documentWidth - (overlayPoint.x + this._overlayRect.width)}px`;\n    } else {\n      styles.left = coerceCssPixelValue(overlayPoint.x);\n    }\n    return styles;\n  }\n  /**\n   * Gets the view properties of the trigger and overlay, including whether they are clipped\n   * or completely outside the view of any of the strategy's scrollables.\n   */\n  _getScrollVisibility() {\n    // Note: needs fresh rects since the position could've changed.\n    const originBounds = this._getOriginRect();\n    const overlayBounds = this._pane.getBoundingClientRect();\n    // TODO(jelbourn): instead of needing all of the client rects for these scrolling containers\n    // every time, we should be able to use the scrollTop of the containers if the size of those\n    // containers hasn't changed.\n    const scrollContainerBounds = this._scrollables.map(scrollable => {\n      return scrollable.getElementRef().nativeElement.getBoundingClientRect();\n    });\n    return {\n      isOriginClipped: isElementClippedByScrolling(originBounds, scrollContainerBounds),\n      isOriginOutsideView: isElementScrolledOutsideView(originBounds, scrollContainerBounds),\n      isOverlayClipped: isElementClippedByScrolling(overlayBounds, scrollContainerBounds),\n      isOverlayOutsideView: isElementScrolledOutsideView(overlayBounds, scrollContainerBounds)\n    };\n  }\n  /** Subtracts the amount that an element is overflowing on an axis from its length. */\n  _subtractOverflows(length, ...overflows) {\n    return overflows.reduce((currentValue, currentOverflow) => {\n      return currentValue - Math.max(currentOverflow, 0);\n    }, length);\n  }\n  /** Narrows the given viewport rect by the current _viewportMargin. */\n  _getNarrowedViewportRect() {\n    // We recalculate the viewport rect here ourselves, rather than using the ViewportRuler,\n    // because we want to use the `clientWidth` and `clientHeight` as the base. The difference\n    // being that the client properties don't include the scrollbar, as opposed to `innerWidth`\n    // and `innerHeight` that do. This is necessary, because the overlay container uses\n    // 100% `width` and `height` which don't include the scrollbar either.\n    const width = this._document.documentElement.clientWidth;\n    const height = this._document.documentElement.clientHeight;\n    const scrollPosition = this._viewportRuler.getViewportScrollPosition();\n    return {\n      top: scrollPosition.top + this._viewportMargin,\n      left: scrollPosition.left + this._viewportMargin,\n      right: scrollPosition.left + width - this._viewportMargin,\n      bottom: scrollPosition.top + height - this._viewportMargin,\n      width: width - 2 * this._viewportMargin,\n      height: height - 2 * this._viewportMargin\n    };\n  }\n  /** Whether the we're dealing with an RTL context */\n  _isRtl() {\n    return this._overlayRef.getDirection() === 'rtl';\n  }\n  /** Determines whether the overlay uses exact or flexible positioning. */\n  _hasExactPosition() {\n    return !this._hasFlexibleDimensions || this._isPushed;\n  }\n  /** Retrieves the offset of a position along the x or y axis. */\n  _getOffset(position, axis) {\n    if (axis === 'x') {\n      // We don't do something like `position['offset' + axis]` in\n      // order to avoid breaking minifiers that rename properties.\n      return position.offsetX == null ? this._offsetX : position.offsetX;\n    }\n    return position.offsetY == null ? this._offsetY : position.offsetY;\n  }\n  /** Validates that the current position match the expected values. */\n  _validatePositions() {\n    if (typeof ngDevMode === 'undefined' || ngDevMode) {\n      if (!this._preferredPositions.length) {\n        throw Error('FlexibleConnectedPositionStrategy: At least one position is required.');\n      }\n      // TODO(crisbeto): remove these once Angular's template type\n      // checking is advanced enough to catch these cases.\n      this._preferredPositions.forEach(pair => {\n        validateHorizontalPosition('originX', pair.originX);\n        validateVerticalPosition('originY', pair.originY);\n        validateHorizontalPosition('overlayX', pair.overlayX);\n        validateVerticalPosition('overlayY', pair.overlayY);\n      });\n    }\n  }\n  /** Adds a single CSS class or an array of classes on the overlay panel. */\n  _addPanelClasses(cssClasses) {\n    if (this._pane) {\n      coerceArray(cssClasses).forEach(cssClass => {\n        if (cssClass !== '' && this._appliedPanelClasses.indexOf(cssClass) === -1) {\n          this._appliedPanelClasses.push(cssClass);\n          this._pane.classList.add(cssClass);\n        }\n      });\n    }\n  }\n  /** Clears the classes that the position strategy has applied from the overlay panel. */\n  _clearPanelClasses() {\n    if (this._pane) {\n      this._appliedPanelClasses.forEach(cssClass => {\n        this._pane.classList.remove(cssClass);\n      });\n      this._appliedPanelClasses = [];\n    }\n  }\n  /** Returns the DOMRect of the current origin. */\n  _getOriginRect() {\n    const origin = this._origin;\n    if (origin instanceof ElementRef) {\n      return origin.nativeElement.getBoundingClientRect();\n    }\n    // Check for Element so SVG elements are also supported.\n    if (origin instanceof Element) {\n      return origin.getBoundingClientRect();\n    }\n    const width = origin.width || 0;\n    const height = origin.height || 0;\n    // If the origin is a point, return a client rect as if it was a 0x0 element at the point.\n    return {\n      top: origin.y,\n      bottom: origin.y + height,\n      left: origin.x,\n      right: origin.x + width,\n      height,\n      width\n    };\n  }\n}\n/** Shallow-extends a stylesheet object with another stylesheet object. */\nfunction extendStyles(destination, source) {\n  for (let key in source) {\n    if (source.hasOwnProperty(key)) {\n      destination[key] = source[key];\n    }\n  }\n  return destination;\n}\n/**\n * Extracts the pixel value as a number from a value, if it's a number\n * or a CSS pixel string (e.g. `1337px`). Otherwise returns null.\n */\nfunction getPixelValue(input) {\n  if (typeof input !== 'number' && input != null) {\n    const [value, units] = input.split(cssUnitPattern);\n    return !units || units === 'px' ? parseFloat(value) : null;\n  }\n  return input || null;\n}\n/**\n * Gets a version of an element's bounding `DOMRect` where all the values are rounded down to\n * the nearest pixel. This allows us to account for the cases where there may be sub-pixel\n * deviations in the `DOMRect` returned by the browser (e.g. when zoomed in with a percentage\n * size, see #21350).\n */\nfunction getRoundedBoundingClientRect(clientRect) {\n  return {\n    top: Math.floor(clientRect.top),\n    right: Math.floor(clientRect.right),\n    bottom: Math.floor(clientRect.bottom),\n    left: Math.floor(clientRect.left),\n    width: Math.floor(clientRect.width),\n    height: Math.floor(clientRect.height)\n  };\n}\n/** Returns whether two `ScrollingVisibility` objects are identical. */\nfunction compareScrollVisibility(a, b) {\n  if (a === b) {\n    return true;\n  }\n  return a.isOriginClipped === b.isOriginClipped && a.isOriginOutsideView === b.isOriginOutsideView && a.isOverlayClipped === b.isOverlayClipped && a.isOverlayOutsideView === b.isOverlayOutsideView;\n}\nconst STANDARD_DROPDOWN_BELOW_POSITIONS = [{\n  originX: 'start',\n  originY: 'bottom',\n  overlayX: 'start',\n  overlayY: 'top'\n}, {\n  originX: 'start',\n  originY: 'top',\n  overlayX: 'start',\n  overlayY: 'bottom'\n}, {\n  originX: 'end',\n  originY: 'bottom',\n  overlayX: 'end',\n  overlayY: 'top'\n}, {\n  originX: 'end',\n  originY: 'top',\n  overlayX: 'end',\n  overlayY: 'bottom'\n}];\nconst STANDARD_DROPDOWN_ADJACENT_POSITIONS = [{\n  originX: 'end',\n  originY: 'top',\n  overlayX: 'start',\n  overlayY: 'top'\n}, {\n  originX: 'end',\n  originY: 'bottom',\n  overlayX: 'start',\n  overlayY: 'bottom'\n}, {\n  originX: 'start',\n  originY: 'top',\n  overlayX: 'end',\n  overlayY: 'top'\n}, {\n  originX: 'start',\n  originY: 'bottom',\n  overlayX: 'end',\n  overlayY: 'bottom'\n}];\n\n/** Class to be added to the overlay pane wrapper. */\nconst wrapperClass = 'cdk-global-overlay-wrapper';\n/**\n * A strategy for positioning overlays. Using this strategy, an overlay is given an\n * explicit position relative to the browser's viewport. We use flexbox, instead of\n * transforms, in order to avoid issues with subpixel rendering which can cause the\n * element to become blurry.\n */\nclass GlobalPositionStrategy {\n  constructor() {\n    this._cssPosition = 'static';\n    this._topOffset = '';\n    this._bottomOffset = '';\n    this._alignItems = '';\n    this._xPosition = '';\n    this._xOffset = '';\n    this._width = '';\n    this._height = '';\n    this._isDisposed = false;\n  }\n  attach(overlayRef) {\n    const config = overlayRef.getConfig();\n    this._overlayRef = overlayRef;\n    if (this._width && !config.width) {\n      overlayRef.updateSize({\n        width: this._width\n      });\n    }\n    if (this._height && !config.height) {\n      overlayRef.updateSize({\n        height: this._height\n      });\n    }\n    overlayRef.hostElement.classList.add(wrapperClass);\n    this._isDisposed = false;\n  }\n  /**\n   * Sets the top position of the overlay. Clears any previously set vertical position.\n   * @param value New top offset.\n   */\n  top(value = '') {\n    this._bottomOffset = '';\n    this._topOffset = value;\n    this._alignItems = 'flex-start';\n    return this;\n  }\n  /**\n   * Sets the left position of the overlay. Clears any previously set horizontal position.\n   * @param value New left offset.\n   */\n  left(value = '') {\n    this._xOffset = value;\n    this._xPosition = 'left';\n    return this;\n  }\n  /**\n   * Sets the bottom position of the overlay. Clears any previously set vertical position.\n   * @param value New bottom offset.\n   */\n  bottom(value = '') {\n    this._topOffset = '';\n    this._bottomOffset = value;\n    this._alignItems = 'flex-end';\n    return this;\n  }\n  /**\n   * Sets the right position of the overlay. Clears any previously set horizontal position.\n   * @param value New right offset.\n   */\n  right(value = '') {\n    this._xOffset = value;\n    this._xPosition = 'right';\n    return this;\n  }\n  /**\n   * Sets the overlay to the start of the viewport, depending on the overlay direction.\n   * This will be to the left in LTR layouts and to the right in RTL.\n   * @param offset Offset from the edge of the screen.\n   */\n  start(value = '') {\n    this._xOffset = value;\n    this._xPosition = 'start';\n    return this;\n  }\n  /**\n   * Sets the overlay to the end of the viewport, depending on the overlay direction.\n   * This will be to the right in LTR layouts and to the left in RTL.\n   * @param offset Offset from the edge of the screen.\n   */\n  end(value = '') {\n    this._xOffset = value;\n    this._xPosition = 'end';\n    return this;\n  }\n  /**\n   * Sets the overlay width and clears any previously set width.\n   * @param value New width for the overlay\n   * @deprecated Pass the `width` through the `OverlayConfig`.\n   * @breaking-change 8.0.0\n   */\n  width(value = '') {\n    if (this._overlayRef) {\n      this._overlayRef.updateSize({\n        width: value\n      });\n    } else {\n      this._width = value;\n    }\n    return this;\n  }\n  /**\n   * Sets the overlay height and clears any previously set height.\n   * @param value New height for the overlay\n   * @deprecated Pass the `height` through the `OverlayConfig`.\n   * @breaking-change 8.0.0\n   */\n  height(value = '') {\n    if (this._overlayRef) {\n      this._overlayRef.updateSize({\n        height: value\n      });\n    } else {\n      this._height = value;\n    }\n    return this;\n  }\n  /**\n   * Centers the overlay horizontally with an optional offset.\n   * Clears any previously set horizontal position.\n   *\n   * @param offset Overlay offset from the horizontal center.\n   */\n  centerHorizontally(offset = '') {\n    this.left(offset);\n    this._xPosition = 'center';\n    return this;\n  }\n  /**\n   * Centers the overlay vertically with an optional offset.\n   * Clears any previously set vertical position.\n   *\n   * @param offset Overlay offset from the vertical center.\n   */\n  centerVertically(offset = '') {\n    this.top(offset);\n    this._alignItems = 'center';\n    return this;\n  }\n  /**\n   * Apply the position to the element.\n   * @docs-private\n   */\n  apply() {\n    // Since the overlay ref applies the strategy asynchronously, it could\n    // have been disposed before it ends up being applied. If that is the\n    // case, we shouldn't do anything.\n    if (!this._overlayRef || !this._overlayRef.hasAttached()) {\n      return;\n    }\n    const styles = this._overlayRef.overlayElement.style;\n    const parentStyles = this._overlayRef.hostElement.style;\n    const config = this._overlayRef.getConfig();\n    const {\n      width,\n      height,\n      maxWidth,\n      maxHeight\n    } = config;\n    const shouldBeFlushHorizontally = (width === '100%' || width === '100vw') && (!maxWidth || maxWidth === '100%' || maxWidth === '100vw');\n    const shouldBeFlushVertically = (height === '100%' || height === '100vh') && (!maxHeight || maxHeight === '100%' || maxHeight === '100vh');\n    const xPosition = this._xPosition;\n    const xOffset = this._xOffset;\n    const isRtl = this._overlayRef.getConfig().direction === 'rtl';\n    let marginLeft = '';\n    let marginRight = '';\n    let justifyContent = '';\n    if (shouldBeFlushHorizontally) {\n      justifyContent = 'flex-start';\n    } else if (xPosition === 'center') {\n      justifyContent = 'center';\n      if (isRtl) {\n        marginRight = xOffset;\n      } else {\n        marginLeft = xOffset;\n      }\n    } else if (isRtl) {\n      if (xPosition === 'left' || xPosition === 'end') {\n        justifyContent = 'flex-end';\n        marginLeft = xOffset;\n      } else if (xPosition === 'right' || xPosition === 'start') {\n        justifyContent = 'flex-start';\n        marginRight = xOffset;\n      }\n    } else if (xPosition === 'left' || xPosition === 'start') {\n      justifyContent = 'flex-start';\n      marginLeft = xOffset;\n    } else if (xPosition === 'right' || xPosition === 'end') {\n      justifyContent = 'flex-end';\n      marginRight = xOffset;\n    }\n    styles.position = this._cssPosition;\n    styles.marginLeft = shouldBeFlushHorizontally ? '0' : marginLeft;\n    styles.marginTop = shouldBeFlushVertically ? '0' : this._topOffset;\n    styles.marginBottom = this._bottomOffset;\n    styles.marginRight = shouldBeFlushHorizontally ? '0' : marginRight;\n    parentStyles.justifyContent = justifyContent;\n    parentStyles.alignItems = shouldBeFlushVertically ? 'flex-start' : this._alignItems;\n  }\n  /**\n   * Cleans up the DOM changes from the position strategy.\n   * @docs-private\n   */\n  dispose() {\n    if (this._isDisposed || !this._overlayRef) {\n      return;\n    }\n    const styles = this._overlayRef.overlayElement.style;\n    const parent = this._overlayRef.hostElement;\n    const parentStyles = parent.style;\n    parent.classList.remove(wrapperClass);\n    parentStyles.justifyContent = parentStyles.alignItems = styles.marginTop = styles.marginBottom = styles.marginLeft = styles.marginRight = styles.position = '';\n    this._overlayRef = null;\n    this._isDisposed = true;\n  }\n}\n\n/** Builder for overlay position strategy. */\nlet OverlayPositionBuilder = /*#__PURE__*/(() => {\n  class OverlayPositionBuilder {\n    constructor(_viewportRuler, _document, _platform, _overlayContainer) {\n      this._viewportRuler = _viewportRuler;\n      this._document = _document;\n      this._platform = _platform;\n      this._overlayContainer = _overlayContainer;\n    }\n    /**\n     * Creates a global position strategy.\n     */\n    global() {\n      return new GlobalPositionStrategy();\n    }\n    /**\n     * Creates a flexible position strategy.\n     * @param origin Origin relative to which to position the overlay.\n     */\n    flexibleConnectedTo(origin) {\n      return new FlexibleConnectedPositionStrategy(origin, this._viewportRuler, this._document, this._platform, this._overlayContainer);\n    }\n    static #_ = this.ɵfac = function OverlayPositionBuilder_Factory(t) {\n      return new (t || OverlayPositionBuilder)(i0.ɵɵinject(i1.ViewportRuler), i0.ɵɵinject(DOCUMENT), i0.ɵɵinject(i1$1.Platform), i0.ɵɵinject(OverlayContainer));\n    };\n    static #_2 = this.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n      token: OverlayPositionBuilder,\n      factory: OverlayPositionBuilder.ɵfac,\n      providedIn: 'root'\n    });\n  }\n  return OverlayPositionBuilder;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/** Next overlay unique ID. */\nlet nextUniqueId = 0;\n// Note that Overlay is *not* scoped to the app root because of the ComponentFactoryResolver\n// which needs to be different depending on where OverlayModule is imported.\n/**\n * Service to create Overlays. Overlays are dynamically added pieces of floating UI, meant to be\n * used as a low-level building block for other components. Dialogs, tooltips, menus,\n * selects, etc. can all be built using overlays. The service should primarily be used by authors\n * of re-usable components rather than developers building end-user applications.\n *\n * An overlay *is* a PortalOutlet, so any kind of Portal can be loaded into one.\n */\nlet Overlay = /*#__PURE__*/(() => {\n  class Overlay {\n    constructor( /** Scrolling strategies that can be used when creating an overlay. */\n    scrollStrategies, _overlayContainer, _componentFactoryResolver, _positionBuilder, _keyboardDispatcher, _injector, _ngZone, _document, _directionality, _location, _outsideClickDispatcher, _animationsModuleType) {\n      this.scrollStrategies = scrollStrategies;\n      this._overlayContainer = _overlayContainer;\n      this._componentFactoryResolver = _componentFactoryResolver;\n      this._positionBuilder = _positionBuilder;\n      this._keyboardDispatcher = _keyboardDispatcher;\n      this._injector = _injector;\n      this._ngZone = _ngZone;\n      this._document = _document;\n      this._directionality = _directionality;\n      this._location = _location;\n      this._outsideClickDispatcher = _outsideClickDispatcher;\n      this._animationsModuleType = _animationsModuleType;\n    }\n    /**\n     * Creates an overlay.\n     * @param config Configuration applied to the overlay.\n     * @returns Reference to the created overlay.\n     */\n    create(config) {\n      const host = this._createHostElement();\n      const pane = this._createPaneElement(host);\n      const portalOutlet = this._createPortalOutlet(pane);\n      const overlayConfig = new OverlayConfig(config);\n      overlayConfig.direction = overlayConfig.direction || this._directionality.value;\n      return new OverlayRef(portalOutlet, host, pane, overlayConfig, this._ngZone, this._keyboardDispatcher, this._document, this._location, this._outsideClickDispatcher, this._animationsModuleType === 'NoopAnimations');\n    }\n    /**\n     * Gets a position builder that can be used, via fluent API,\n     * to construct and configure a position strategy.\n     * @returns An overlay position builder.\n     */\n    position() {\n      return this._positionBuilder;\n    }\n    /**\n     * Creates the DOM element for an overlay and appends it to the overlay container.\n     * @returns Newly-created pane element\n     */\n    _createPaneElement(host) {\n      const pane = this._document.createElement('div');\n      pane.id = `cdk-overlay-${nextUniqueId++}`;\n      pane.classList.add('cdk-overlay-pane');\n      host.appendChild(pane);\n      return pane;\n    }\n    /**\n     * Creates the host element that wraps around an overlay\n     * and can be used for advanced positioning.\n     * @returns Newly-create host element.\n     */\n    _createHostElement() {\n      const host = this._document.createElement('div');\n      this._overlayContainer.getContainerElement().appendChild(host);\n      return host;\n    }\n    /**\n     * Create a DomPortalOutlet into which the overlay content can be loaded.\n     * @param pane The DOM element to turn into a portal outlet.\n     * @returns A portal outlet for the given DOM element.\n     */\n    _createPortalOutlet(pane) {\n      // We have to resolve the ApplicationRef later in order to allow people\n      // to use overlay-based providers during app initialization.\n      if (!this._appRef) {\n        this._appRef = this._injector.get(ApplicationRef);\n      }\n      return new DomPortalOutlet(pane, this._componentFactoryResolver, this._appRef, this._injector, this._document);\n    }\n    static #_ = this.ɵfac = function Overlay_Factory(t) {\n      return new (t || Overlay)(i0.ɵɵinject(ScrollStrategyOptions), i0.ɵɵinject(OverlayContainer), i0.ɵɵinject(i0.ComponentFactoryResolver), i0.ɵɵinject(OverlayPositionBuilder), i0.ɵɵinject(OverlayKeyboardDispatcher), i0.ɵɵinject(i0.Injector), i0.ɵɵinject(i0.NgZone), i0.ɵɵinject(DOCUMENT), i0.ɵɵinject(i5.Directionality), i0.ɵɵinject(i6.Location), i0.ɵɵinject(OverlayOutsideClickDispatcher), i0.ɵɵinject(ANIMATION_MODULE_TYPE, 8));\n    };\n    static #_2 = this.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n      token: Overlay,\n      factory: Overlay.ɵfac,\n      providedIn: 'root'\n    });\n  }\n  return Overlay;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/** Default set of positions for the overlay. Follows the behavior of a dropdown. */\nconst defaultPositionList = [{\n  originX: 'start',\n  originY: 'bottom',\n  overlayX: 'start',\n  overlayY: 'top'\n}, {\n  originX: 'start',\n  originY: 'top',\n  overlayX: 'start',\n  overlayY: 'bottom'\n}, {\n  originX: 'end',\n  originY: 'top',\n  overlayX: 'end',\n  overlayY: 'bottom'\n}, {\n  originX: 'end',\n  originY: 'bottom',\n  overlayX: 'end',\n  overlayY: 'top'\n}];\n/** Injection token that determines the scroll handling while the connected overlay is open. */\nconst CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY = /*#__PURE__*/new InjectionToken('cdk-connected-overlay-scroll-strategy', {\n  providedIn: 'root',\n  factory: () => {\n    const overlay = inject(Overlay);\n    return () => overlay.scrollStrategies.reposition();\n  }\n});\n/**\n * Directive applied to an element to make it usable as an origin for an Overlay using a\n * ConnectedPositionStrategy.\n */\nlet CdkOverlayOrigin = /*#__PURE__*/(() => {\n  class CdkOverlayOrigin {\n    constructor( /** Reference to the element on which the directive is applied. */\n    elementRef) {\n      this.elementRef = elementRef;\n    }\n    static #_ = this.ɵfac = function CdkOverlayOrigin_Factory(t) {\n      return new (t || CdkOverlayOrigin)(i0.ɵɵdirectiveInject(i0.ElementRef));\n    };\n    static #_2 = this.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n      type: CdkOverlayOrigin,\n      selectors: [[\"\", \"cdk-overlay-origin\", \"\"], [\"\", \"overlay-origin\", \"\"], [\"\", \"cdkOverlayOrigin\", \"\"]],\n      exportAs: [\"cdkOverlayOrigin\"],\n      standalone: true\n    });\n  }\n  return CdkOverlayOrigin;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * Directive to facilitate declarative creation of an\n * Overlay using a FlexibleConnectedPositionStrategy.\n */\nlet CdkConnectedOverlay = /*#__PURE__*/(() => {\n  class CdkConnectedOverlay {\n    /** The offset in pixels for the overlay connection point on the x-axis */\n    get offsetX() {\n      return this._offsetX;\n    }\n    set offsetX(offsetX) {\n      this._offsetX = offsetX;\n      if (this._position) {\n        this._updatePositionStrategy(this._position);\n      }\n    }\n    /** The offset in pixels for the overlay connection point on the y-axis */\n    get offsetY() {\n      return this._offsetY;\n    }\n    set offsetY(offsetY) {\n      this._offsetY = offsetY;\n      if (this._position) {\n        this._updatePositionStrategy(this._position);\n      }\n    }\n    /** Whether the overlay should be disposed of when the user goes backwards/forwards in history. */\n    get disposeOnNavigation() {\n      return this._disposeOnNavigation;\n    }\n    set disposeOnNavigation(value) {\n      this._disposeOnNavigation = value;\n    }\n    // TODO(jelbourn): inputs for size, scroll behavior, animation, etc.\n    constructor(_overlay, templateRef, viewContainerRef, scrollStrategyFactory, _dir) {\n      this._overlay = _overlay;\n      this._dir = _dir;\n      this._backdropSubscription = Subscription.EMPTY;\n      this._attachSubscription = Subscription.EMPTY;\n      this._detachSubscription = Subscription.EMPTY;\n      this._positionSubscription = Subscription.EMPTY;\n      this._disposeOnNavigation = false;\n      this._ngZone = inject(NgZone);\n      /** Margin between the overlay and the viewport edges. */\n      this.viewportMargin = 0;\n      /** Whether the overlay is open. */\n      this.open = false;\n      /** Whether the overlay can be closed by user interaction. */\n      this.disableClose = false;\n      /** Whether or not the overlay should attach a backdrop. */\n      this.hasBackdrop = false;\n      /** Whether or not the overlay should be locked when scrolling. */\n      this.lockPosition = false;\n      /** Whether the overlay's width and height can be constrained to fit within the viewport. */\n      this.flexibleDimensions = false;\n      /** Whether the overlay can grow after the initial open when flexible positioning is turned on. */\n      this.growAfterOpen = false;\n      /** Whether the overlay can be pushed on-screen if none of the provided positions fit. */\n      this.push = false;\n      /** Event emitted when the backdrop is clicked. */\n      this.backdropClick = new EventEmitter();\n      /** Event emitted when the position has changed. */\n      this.positionChange = new EventEmitter();\n      /** Event emitted when the overlay has been attached. */\n      this.attach = new EventEmitter();\n      /** Event emitted when the overlay has been detached. */\n      this.detach = new EventEmitter();\n      /** Emits when there are keyboard events that are targeted at the overlay. */\n      this.overlayKeydown = new EventEmitter();\n      /** Emits when there are mouse outside click events that are targeted at the overlay. */\n      this.overlayOutsideClick = new EventEmitter();\n      this._templatePortal = new TemplatePortal(templateRef, viewContainerRef);\n      this._scrollStrategyFactory = scrollStrategyFactory;\n      this.scrollStrategy = this._scrollStrategyFactory();\n    }\n    /** The associated overlay reference. */\n    get overlayRef() {\n      return this._overlayRef;\n    }\n    /** The element's layout direction. */\n    get dir() {\n      return this._dir ? this._dir.value : 'ltr';\n    }\n    ngOnDestroy() {\n      this._attachSubscription.unsubscribe();\n      this._detachSubscription.unsubscribe();\n      this._backdropSubscription.unsubscribe();\n      this._positionSubscription.unsubscribe();\n      if (this._overlayRef) {\n        this._overlayRef.dispose();\n      }\n    }\n    ngOnChanges(changes) {\n      if (this._position) {\n        this._updatePositionStrategy(this._position);\n        this._overlayRef.updateSize({\n          width: this.width,\n          minWidth: this.minWidth,\n          height: this.height,\n          minHeight: this.minHeight\n        });\n        if (changes['origin'] && this.open) {\n          this._position.apply();\n        }\n      }\n      if (changes['open']) {\n        this.open ? this._attachOverlay() : this._detachOverlay();\n      }\n    }\n    /** Creates an overlay */\n    _createOverlay() {\n      if (!this.positions || !this.positions.length) {\n        this.positions = defaultPositionList;\n      }\n      const overlayRef = this._overlayRef = this._overlay.create(this._buildConfig());\n      this._attachSubscription = overlayRef.attachments().subscribe(() => this.attach.emit());\n      this._detachSubscription = overlayRef.detachments().subscribe(() => this.detach.emit());\n      overlayRef.keydownEvents().subscribe(event => {\n        this.overlayKeydown.next(event);\n        if (event.keyCode === ESCAPE && !this.disableClose && !hasModifierKey(event)) {\n          event.preventDefault();\n          this._detachOverlay();\n        }\n      });\n      this._overlayRef.outsidePointerEvents().subscribe(event => {\n        const origin = this._getOriginElement();\n        const target = _getEventTarget(event);\n        if (!origin || origin !== target && !origin.contains(target)) {\n          this.overlayOutsideClick.next(event);\n        }\n      });\n    }\n    /** Builds the overlay config based on the directive's inputs */\n    _buildConfig() {\n      const positionStrategy = this._position = this.positionStrategy || this._createPositionStrategy();\n      const overlayConfig = new OverlayConfig({\n        direction: this._dir,\n        positionStrategy,\n        scrollStrategy: this.scrollStrategy,\n        hasBackdrop: this.hasBackdrop,\n        disposeOnNavigation: this.disposeOnNavigation\n      });\n      if (this.width || this.width === 0) {\n        overlayConfig.width = this.width;\n      }\n      if (this.height || this.height === 0) {\n        overlayConfig.height = this.height;\n      }\n      if (this.minWidth || this.minWidth === 0) {\n        overlayConfig.minWidth = this.minWidth;\n      }\n      if (this.minHeight || this.minHeight === 0) {\n        overlayConfig.minHeight = this.minHeight;\n      }\n      if (this.backdropClass) {\n        overlayConfig.backdropClass = this.backdropClass;\n      }\n      if (this.panelClass) {\n        overlayConfig.panelClass = this.panelClass;\n      }\n      return overlayConfig;\n    }\n    /** Updates the state of a position strategy, based on the values of the directive inputs. */\n    _updatePositionStrategy(positionStrategy) {\n      const positions = this.positions.map(currentPosition => ({\n        originX: currentPosition.originX,\n        originY: currentPosition.originY,\n        overlayX: currentPosition.overlayX,\n        overlayY: currentPosition.overlayY,\n        offsetX: currentPosition.offsetX || this.offsetX,\n        offsetY: currentPosition.offsetY || this.offsetY,\n        panelClass: currentPosition.panelClass || undefined\n      }));\n      return positionStrategy.setOrigin(this._getOrigin()).withPositions(positions).withFlexibleDimensions(this.flexibleDimensions).withPush(this.push).withGrowAfterOpen(this.growAfterOpen).withViewportMargin(this.viewportMargin).withLockedPosition(this.lockPosition).withTransformOriginOn(this.transformOriginSelector);\n    }\n    /** Returns the position strategy of the overlay to be set on the overlay config */\n    _createPositionStrategy() {\n      const strategy = this._overlay.position().flexibleConnectedTo(this._getOrigin());\n      this._updatePositionStrategy(strategy);\n      return strategy;\n    }\n    _getOrigin() {\n      if (this.origin instanceof CdkOverlayOrigin) {\n        return this.origin.elementRef;\n      } else {\n        return this.origin;\n      }\n    }\n    _getOriginElement() {\n      if (this.origin instanceof CdkOverlayOrigin) {\n        return this.origin.elementRef.nativeElement;\n      }\n      if (this.origin instanceof ElementRef) {\n        return this.origin.nativeElement;\n      }\n      if (typeof Element !== 'undefined' && this.origin instanceof Element) {\n        return this.origin;\n      }\n      return null;\n    }\n    /** Attaches the overlay and subscribes to backdrop clicks if backdrop exists */\n    _attachOverlay() {\n      if (!this._overlayRef) {\n        this._createOverlay();\n      } else {\n        // Update the overlay size, in case the directive's inputs have changed\n        this._overlayRef.getConfig().hasBackdrop = this.hasBackdrop;\n      }\n      if (!this._overlayRef.hasAttached()) {\n        this._overlayRef.attach(this._templatePortal);\n      }\n      if (this.hasBackdrop) {\n        this._backdropSubscription = this._overlayRef.backdropClick().subscribe(event => {\n          this.backdropClick.emit(event);\n        });\n      } else {\n        this._backdropSubscription.unsubscribe();\n      }\n      this._positionSubscription.unsubscribe();\n      // Only subscribe to `positionChanges` if requested, because putting\n      // together all the information for it can be expensive.\n      if (this.positionChange.observers.length > 0) {\n        this._positionSubscription = this._position.positionChanges.pipe(takeWhile(() => this.positionChange.observers.length > 0)).subscribe(position => {\n          this._ngZone.run(() => this.positionChange.emit(position));\n          if (this.positionChange.observers.length === 0) {\n            this._positionSubscription.unsubscribe();\n          }\n        });\n      }\n    }\n    /** Detaches the overlay and unsubscribes to backdrop clicks if backdrop exists */\n    _detachOverlay() {\n      if (this._overlayRef) {\n        this._overlayRef.detach();\n      }\n      this._backdropSubscription.unsubscribe();\n      this._positionSubscription.unsubscribe();\n    }\n    static #_ = this.ɵfac = function CdkConnectedOverlay_Factory(t) {\n      return new (t || CdkConnectedOverlay)(i0.ɵɵdirectiveInject(Overlay), i0.ɵɵdirectiveInject(i0.TemplateRef), i0.ɵɵdirectiveInject(i0.ViewContainerRef), i0.ɵɵdirectiveInject(CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY), i0.ɵɵdirectiveInject(i5.Directionality, 8));\n    };\n    static #_2 = this.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n      type: CdkConnectedOverlay,\n      selectors: [[\"\", \"cdk-connected-overlay\", \"\"], [\"\", \"connected-overlay\", \"\"], [\"\", \"cdkConnectedOverlay\", \"\"]],\n      inputs: {\n        origin: [i0.ɵɵInputFlags.None, \"cdkConnectedOverlayOrigin\", \"origin\"],\n        positions: [i0.ɵɵInputFlags.None, \"cdkConnectedOverlayPositions\", \"positions\"],\n        positionStrategy: [i0.ɵɵInputFlags.None, \"cdkConnectedOverlayPositionStrategy\", \"positionStrategy\"],\n        offsetX: [i0.ɵɵInputFlags.None, \"cdkConnectedOverlayOffsetX\", \"offsetX\"],\n        offsetY: [i0.ɵɵInputFlags.None, \"cdkConnectedOverlayOffsetY\", \"offsetY\"],\n        width: [i0.ɵɵInputFlags.None, \"cdkConnectedOverlayWidth\", \"width\"],\n        height: [i0.ɵɵInputFlags.None, \"cdkConnectedOverlayHeight\", \"height\"],\n        minWidth: [i0.ɵɵInputFlags.None, \"cdkConnectedOverlayMinWidth\", \"minWidth\"],\n        minHeight: [i0.ɵɵInputFlags.None, \"cdkConnectedOverlayMinHeight\", \"minHeight\"],\n        backdropClass: [i0.ɵɵInputFlags.None, \"cdkConnectedOverlayBackdropClass\", \"backdropClass\"],\n        panelClass: [i0.ɵɵInputFlags.None, \"cdkConnectedOverlayPanelClass\", \"panelClass\"],\n        viewportMargin: [i0.ɵɵInputFlags.None, \"cdkConnectedOverlayViewportMargin\", \"viewportMargin\"],\n        scrollStrategy: [i0.ɵɵInputFlags.None, \"cdkConnectedOverlayScrollStrategy\", \"scrollStrategy\"],\n        open: [i0.ɵɵInputFlags.None, \"cdkConnectedOverlayOpen\", \"open\"],\n        disableClose: [i0.ɵɵInputFlags.None, \"cdkConnectedOverlayDisableClose\", \"disableClose\"],\n        transformOriginSelector: [i0.ɵɵInputFlags.None, \"cdkConnectedOverlayTransformOriginOn\", \"transformOriginSelector\"],\n        hasBackdrop: [i0.ɵɵInputFlags.HasDecoratorInputTransform, \"cdkConnectedOverlayHasBackdrop\", \"hasBackdrop\", booleanAttribute],\n        lockPosition: [i0.ɵɵInputFlags.HasDecoratorInputTransform, \"cdkConnectedOverlayLockPosition\", \"lockPosition\", booleanAttribute],\n        flexibleDimensions: [i0.ɵɵInputFlags.HasDecoratorInputTransform, \"cdkConnectedOverlayFlexibleDimensions\", \"flexibleDimensions\", booleanAttribute],\n        growAfterOpen: [i0.ɵɵInputFlags.HasDecoratorInputTransform, \"cdkConnectedOverlayGrowAfterOpen\", \"growAfterOpen\", booleanAttribute],\n        push: [i0.ɵɵInputFlags.HasDecoratorInputTransform, \"cdkConnectedOverlayPush\", \"push\", booleanAttribute],\n        disposeOnNavigation: [i0.ɵɵInputFlags.HasDecoratorInputTransform, \"cdkConnectedOverlayDisposeOnNavigation\", \"disposeOnNavigation\", booleanAttribute]\n      },\n      outputs: {\n        backdropClick: \"backdropClick\",\n        positionChange: \"positionChange\",\n        attach: \"attach\",\n        detach: \"detach\",\n        overlayKeydown: \"overlayKeydown\",\n        overlayOutsideClick: \"overlayOutsideClick\"\n      },\n      exportAs: [\"cdkConnectedOverlay\"],\n      standalone: true,\n      features: [i0.ɵɵInputTransformsFeature, i0.ɵɵNgOnChangesFeature]\n    });\n  }\n  return CdkConnectedOverlay;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/** @docs-private */\nfunction CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER_FACTORY(overlay) {\n  return () => overlay.scrollStrategies.reposition();\n}\n/** @docs-private */\nconst CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER = {\n  provide: CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY,\n  deps: [Overlay],\n  useFactory: CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER_FACTORY\n};\nlet OverlayModule = /*#__PURE__*/(() => {\n  class OverlayModule {\n    static #_ = this.ɵfac = function OverlayModule_Factory(t) {\n      return new (t || OverlayModule)();\n    };\n    static #_2 = this.ɵmod = /* @__PURE__ */i0.ɵɵdefineNgModule({\n      type: OverlayModule\n    });\n    static #_3 = this.ɵinj = /* @__PURE__ */i0.ɵɵdefineInjector({\n      providers: [Overlay, CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY_PROVIDER],\n      imports: [BidiModule, PortalModule, ScrollingModule, ScrollingModule]\n    });\n  }\n  return OverlayModule;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * Alternative to OverlayContainer that supports correct displaying of overlay elements in\n * Fullscreen mode\n * https://developer.mozilla.org/en-US/docs/Web/API/Element/requestFullScreen\n *\n * Should be provided in the root component.\n */\nlet FullscreenOverlayContainer = /*#__PURE__*/(() => {\n  class FullscreenOverlayContainer extends OverlayContainer {\n    constructor(_document, platform) {\n      super(_document, platform);\n    }\n    ngOnDestroy() {\n      super.ngOnDestroy();\n      if (this._fullScreenEventName && this._fullScreenListener) {\n        this._document.removeEventListener(this._fullScreenEventName, this._fullScreenListener);\n      }\n    }\n    _createContainer() {\n      super._createContainer();\n      this._adjustParentForFullscreenChange();\n      this._addFullscreenChangeListener(() => this._adjustParentForFullscreenChange());\n    }\n    _adjustParentForFullscreenChange() {\n      if (!this._containerElement) {\n        return;\n      }\n      const fullscreenElement = this.getFullscreenElement();\n      const parent = fullscreenElement || this._document.body;\n      parent.appendChild(this._containerElement);\n    }\n    _addFullscreenChangeListener(fn) {\n      const eventName = this._getEventName();\n      if (eventName) {\n        if (this._fullScreenListener) {\n          this._document.removeEventListener(eventName, this._fullScreenListener);\n        }\n        this._document.addEventListener(eventName, fn);\n        this._fullScreenListener = fn;\n      }\n    }\n    _getEventName() {\n      if (!this._fullScreenEventName) {\n        const _document = this._document;\n        if (_document.fullscreenEnabled) {\n          this._fullScreenEventName = 'fullscreenchange';\n        } else if (_document.webkitFullscreenEnabled) {\n          this._fullScreenEventName = 'webkitfullscreenchange';\n        } else if (_document.mozFullScreenEnabled) {\n          this._fullScreenEventName = 'mozfullscreenchange';\n        } else if (_document.msFullscreenEnabled) {\n          this._fullScreenEventName = 'MSFullscreenChange';\n        }\n      }\n      return this._fullScreenEventName;\n    }\n    /**\n     * When the page is put into fullscreen mode, a specific element is specified.\n     * Only that element and its children are visible when in fullscreen mode.\n     */\n    getFullscreenElement() {\n      const _document = this._document;\n      return _document.fullscreenElement || _document.webkitFullscreenElement || _document.mozFullScreenElement || _document.msFullscreenElement || null;\n    }\n    static #_ = this.ɵfac = function FullscreenOverlayContainer_Factory(t) {\n      return new (t || FullscreenOverlayContainer)(i0.ɵɵinject(DOCUMENT), i0.ɵɵinject(i1$1.Platform));\n    };\n    static #_2 = this.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n      token: FullscreenOverlayContainer,\n      factory: FullscreenOverlayContainer.ɵfac,\n      providedIn: 'root'\n    });\n  }\n  return FullscreenOverlayContainer;\n})();\n/*#__PURE__*/(() => {\n  (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\n/**\n * Generated bundle index. Do not edit.\n */\n\nexport { BlockScrollStrategy, CdkConnectedOverlay, CdkOverlayOrigin, CloseScrollStrategy, ConnectedOverlayPositionChange, ConnectionPositionPair, FlexibleConnectedPositionStrategy, FullscreenOverlayContainer, GlobalPositionStrategy, NoopScrollStrategy, Overlay, OverlayConfig, OverlayContainer, OverlayKeyboardDispatcher, OverlayModule, OverlayOutsideClickDispatcher, OverlayPositionBuilder, OverlayRef, RepositionScrollStrategy, STANDARD_DROPDOWN_ADJACENT_POSITIONS, STANDARD_DROPDOWN_BELOW_POSITIONS, ScrollStrategyOptions, ScrollingVisibility, validateHorizontalPosition, validateVerticalPosition };\n//# sourceMappingURL=overlay.mjs.map","map":null,"metadata":{},"sourceType":"module","externalDependencies":[]}