text: /**
   * @license
   * Copyright Google LLC All Rights Reserved.
   *
   * Use of this source code is governed by an MIT-style license that can be
   * found in the LICENSE file at https://angular.io/license
   */
  (function (global, factory) {
  	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/cdk/portal'), require('@angular/common'), require('@angular/animations'), require('@angular/cdk/a11y'), require('@angular/material/core'), require('rxjs'), require('@angular/cdk/coercion'), require('@angular/cdk/keycodes'), require('rxjs/operators'), require('@angular/cdk/bidi'), require('@angular/cdk/overlay')) :
  	typeof define === 'function' && define.amd ? define('@angular/material/menu', ['exports', '@angular/core', '@angular/cdk/portal', '@angular/common', '@angular/animations', '@angular/cdk/a11y', '@angular/material/core', 'rxjs', '@angular/cdk/coercion', '@angular/cdk/keycodes', 'rxjs/operators', '@angular/cdk/bidi', '@angular/cdk/overlay'], factory) :
  	(factory((global.ng = global.ng || {}, global.ng.material = global.ng.material || {}, global.ng.material.menu = {}),global.ng.core,global.ng.cdk.portal,global.ng.common,global.ng.animations,global.ng.cdk.a11y,global.ng.material.core,global.rxjs,global.ng.cdk.coercion,global.ng.cdk.keycodes,global.rxjs.operators,global.ng.cdk.bidi,global.ng.cdk.overlay));
  }(this, (function (exports,core,portal,common,animations,a11y,core$1,rxjs,coercion,keycodes,operators,bidi,overlay) { 'use strict';
  
  /*! *****************************************************************************
  Copyright (c) Microsoft Corporation. All rights reserved.
  Licensed under the Apache License, Version 2.0 (the "License"); you may not use
  this file except in compliance with the License. You may obtain a copy of the
  License at http://www.apache.org/licenses/LICENSE-2.0
  
  THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
  WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
  MERCHANTABLITY OR NON-INFRINGEMENT.
  
  See the Apache Version 2.0 License for specific language governing permissions
  and limitations under the License.
  ***************************************************************************** */
  /* global Reflect, Promise */
  
  var extendStatics = function(d, b) {
      extendStatics = Object.setPrototypeOf ||
          ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
          function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
      return extendStatics(d, b);
  };
  
  function __extends(d, b) {
      extendStatics(d, b);
      function __() { this.constructor = d; }
      d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * Menu content that will be rendered lazily once the menu is opened.
   */
  var MatMenuContent = /** @class */ (function () {
      function MatMenuContent(_template, _componentFactoryResolver, _appRef, _injector, _viewContainerRef, _document) {
          this._template = _template;
          this._componentFactoryResolver = _componentFactoryResolver;
          this._appRef = _appRef;
          this._injector = _injector;
          this._viewContainerRef = _viewContainerRef;
          this._document = _document;
      }
      /**
       * Attaches the content with a particular context.
       * @docs-private
       */
      /**
       * Attaches the content with a particular context.
       * \@docs-private
       * @param {?=} context
       * @return {?}
       */
      MatMenuContent.prototype.attach = /**
       * Attaches the content with a particular context.
       * \@docs-private
       * @param {?=} context
       * @return {?}
       */
      function (context) {
          if (context === void 0) { context = {}; }
          if (!this._portal) {
              this._portal = new portal.TemplatePortal(this._template, this._viewContainerRef);
          }
          this.detach();
          if (!this._outlet) {
              this._outlet = new portal.DomPortalOutlet(this._document.createElement('div'), this._componentFactoryResolver, this._appRef, this._injector);
          }
          var /** @type {?} */ element = this._template.elementRef.nativeElement; /** @type {?} */
          ((
          // Because we support opening the same menu from different triggers (which in turn have their
          // own `OverlayRef` panel), we have to re-insert the host element every time, otherwise we
          // risk it staying attached to a pane that's no longer in the DOM.
          element.parentNode)).insertBefore(this._outlet.outletElement, element);
          this._portal.attach(this._outlet, context);
      };
      /**
       * Detaches the content.
       * @docs-private
       */
      /**
       * Detaches the content.
       * \@docs-private
       * @return {?}
       */
      MatMenuContent.prototype.detach = /**
       * Detaches the content.
       * \@docs-private
       * @return {?}
       */
      function () {
          if (this._portal.isAttached) {
              this._portal.detach();
          }
      };
      /**
       * @return {?}
       */
      MatMenuContent.prototype.ngOnDestroy = /**
       * @return {?}
       */
      function () {
          if (this._outlet) {
              this._outlet.dispose();
          }
      };
      MatMenuContent.decorators = [
          { type: core.Directive, args: [{
                      selector: 'ng-template[matMenuContent]'
                  },] },
      ];
      /** @nocollapse */
      MatMenuContent.ctorParameters = function () { return [
          { type: core.TemplateRef, },
          { type: core.ComponentFactoryResolver, },
          { type: core.ApplicationRef, },
          { type: core.Injector, },
          { type: core.ViewContainerRef, },
          { type: undefined, decorators: [{ type: core.Inject, args: [common.DOCUMENT,] },] },
      ]; };
      return MatMenuContent;
  }());
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * Animations used by the mat-menu component.
   * Animation duration and timing values are based on:
   * https://material.io/guidelines/components/menus.html#menus-usage
   */
  var /** @type {?} */ matMenuAnimations = {
      /**
         * This animation controls the menu panel's entry and exit from the page.
         *
         * When the menu panel is added to the DOM, it scales in and fades in its border.
         *
         * When the menu panel is removed from the DOM, it simply fades out after a brief
         * delay to display the ripple.
         */
      transformMenu: animations.trigger('transformMenu', [
          animations.state('void', animations.style({
              opacity: 0,
              // This starts off from 0.01, instead of 0, because there's an issue in the Angular animations
              // as of 4.2, which causes the animation to be skipped if it starts from 0.
              transform: 'scale(0.01, 0.01)'
          })),
          animations.transition('void => enter', animations.sequence([
              animations.query('.mat-menu-content', animations.style({ opacity: 0 })),
              animations.animate('100ms linear', animations.style({ opacity: 1, transform: 'scale(1, 0.5)' })),
              animations.group([
                  animations.query('.mat-menu-content', animations.animate('400ms cubic-bezier(0.55, 0, 0.55, 0.2)', animations.style({ opacity: 1 }))),
                  animations.animate('300ms cubic-bezier(0.25, 0.8, 0.25, 1)', animations.style({ transform: 'scale(1, 1)' })),
              ])
          ])),
          animations.transition('* => void', animations.animate('150ms 50ms linear', animations.style({ opacity: 0 })))
      ]),
      /**
         * This animation fades in the background color and content of the menu panel
         * after its containing element is scaled in.
         */
      fadeInItems: animations.trigger('fadeInItems', [
          // TODO(crisbeto): this is inside the `transformMenu`
          // now. Remove next time we do breaking changes.
          animations.state('showing', animations.style({ opacity: 1 })),
          animations.transition('void => *', [
              animations.style({ opacity: 0 }),
              animations.animate('400ms 100ms cubic-bezier(0.55, 0, 0.55, 0.2)')
          ])
      ])
  };
  /**
   * @deprecated
   * \@deletion-target 7.0.0
   */
  var /** @type {?} */ fadeInItems = matMenuAnimations.fadeInItems;
  /**
   * @deprecated
   * \@deletion-target 7.0.0
   */
  var /** @type {?} */ transformMenu = matMenuAnimations.transformMenu;
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  
  /**
   * Throws an exception for the case when menu trigger doesn't have a valid mat-menu instance
   * \@docs-private
   * @return {?}
   */
  function throwMatMenuMissingError() {
      throw Error("mat-menu-trigger: must pass in an mat-menu instance.\n\n    Example:\n      <mat-menu #menu=\"matMenu\"></mat-menu>\n      <button [matMenuTriggerFor]=\"menu\"></button>");
  }
  /**
   * Throws an exception for the case when menu's x-position value isn't valid.
   * In other words, it doesn't match 'before' or 'after'.
   * \@docs-private
   * @return {?}
   */
  function throwMatMenuInvalidPositionX() {
      throw Error("x-position value must be either 'before' or after'.\n      Example: <mat-menu x-position=\"before\" #menu=\"matMenu\"></mat-menu>");
  }
  /**
   * Throws an exception for the case when menu's y-position value isn't valid.
   * In other words, it doesn't match 'above' or 'below'.
   * \@docs-private
   * @return {?}
   */
  function throwMatMenuInvalidPositionY() {
      throw Error("y-position value must be either 'above' or below'.\n      Example: <mat-menu y-position=\"above\" #menu=\"matMenu\"></mat-menu>");
  }
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * Injection token used to provide the parent menu to menu-specific components.
   * \@docs-private
   */
  var /** @type {?} */ MAT_MENU_PANEL = new core.InjectionToken('MAT_MENU_PANEL');
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * \@docs-private
   */
  var   /**
   * \@docs-private
   */
  MatMenuItemBase = /** @class */ (function () {
      function MatMenuItemBase() {
      }
      return MatMenuItemBase;
  }());
  var /** @type {?} */ _MatMenuItemMixinBase = core$1.mixinDisableRipple(core$1.mixinDisabled(MatMenuItemBase));
  /**
   * This directive is intended to be used inside an mat-menu tag.
   * It exists mostly to set the role attribute.
   */
  var MatMenuItem = /** @class */ (function (_super) {
      __extends(MatMenuItem, _super);
      function MatMenuItem(_elementRef, document, _focusMonitor, _parentMenu) {
          var _this = 
          // @deletion-target 7.0.0 make `_focusMonitor` and `document` required params.
          _super.call(this) || this;
          _this._elementRef = _elementRef;
          _this._focusMonitor = _focusMonitor;
          _this._parentMenu = _parentMenu;
          /**
           * Stream that emits when the menu item is hovered.
           */
          _this._hovered = new rxjs.Subject();
          /**
           * Whether the menu item is highlighted.
           */
          _this._highlighted = false;
          /**
           * Whether the menu item acts as a trigger for a sub-menu.
           */
          _this._triggersSubmenu = false;
          if (_focusMonitor) {
              // Start monitoring the element so it gets the appropriate focused classes. We want
              // to show the focus style for menu items only when the focus was not caused by a
              // mouse or touch interaction.
              _focusMonitor.monitor(_this._getHostElement(), false);
          }
          if (_parentMenu && _parentMenu.addItem) {
              _parentMenu.addItem(_this);
          }
          _this._document = document;
          return _this;
      }
      /** Focuses the menu item. */
      /**
       * Focuses the menu item.
       * @param {?=} origin
       * @return {?}
       */
      MatMenuItem.prototype.focus = /**
       * Focuses the menu item.
       * @param {?=} origin
       * @return {?}
       */
      function (origin) {
          if (origin === void 0) { origin = 'program'; }
          if (this._focusMonitor) {
              this._focusMonitor.focusVia(this._getHostElement(), origin);
          }
          else {
              this._getHostElement().focus();
          }
      };
      /**
       * @return {?}
       */
      MatMenuItem.prototype.ngOnDestroy = /**
       * @return {?}
       */
      function () {
          if (this._focusMonitor) {
              this._focusMonitor.stopMonitoring(this._getHostElement());
          }
          if (this._parentMenu && this._parentMenu.removeItem) {
              this._parentMenu.removeItem(this);
          }
          this._hovered.complete();
      };
      /** Used to set the `tabindex`. */
      /**
       * Used to set the `tabindex`.
       * @return {?}
       */
      MatMenuItem.prototype._getTabIndex = /**
       * Used to set the `tabindex`.
       * @return {?}
       */
      function () {
          return this.disabled ? '-1' : '0';
      };
      /** Returns the host DOM element. */
      /**
       * Returns the host DOM element.
       * @return {?}
       */
      MatMenuItem.prototype._getHostElement = /**
       * Returns the host DOM element.
       * @return {?}
       */
      function () {
          return this._elementRef.nativeElement;
      };
      /** Prevents the default element actions if it is disabled. */
      /**
       * Prevents the default element actions if it is disabled.
       * @param {?} event
       * @return {?}
       */
      MatMenuItem.prototype._checkDisabled = /**
       * Prevents the default element actions if it is disabled.
       * @param {?} event
       * @return {?}
       */
      function (event) {
          if (this.disabled) {
              event.preventDefault();
              event.stopPropagation();
          }
      };
      /** Emits to the hover stream. */
      /**
       * Emits to the hover stream.
       * @return {?}
       */
      MatMenuItem.prototype._handleMouseEnter = /**
       * Emits to the hover stream.
       * @return {?}
       */
      function () {
          this._hovered.next(this);
      };
      /** Gets the label to be used when determining whether the option should be focused. */
      /**
       * Gets the label to be used when determining whether the option should be focused.
       * @return {?}
       */
      MatMenuItem.prototype.getLabel = /**
       * Gets the label to be used when determining whether the option should be focused.
       * @return {?}
       */
      function () {
          var /** @type {?} */ element = this._elementRef.nativeElement;
          var /** @type {?} */ textNodeType = this._document ? this._document.TEXT_NODE : 3;
          var /** @type {?} */ output = '';
          if (element.childNodes) {
              var /** @type {?} */ length_1 = element.childNodes.length;
              // Go through all the top-level text nodes and extract their text.
              // We skip anything that's not a text node to prevent the text from
              // being thrown off by something like an icon.
              for (var /** @type {?} */ i = 0; i < length_1; i++) {
                  if (element.childNodes[i].nodeType === textNodeType) {
                      output += element.childNodes[i].textContent;
                  }
              }
          }
          return output.trim();
      };
      MatMenuItem.decorators = [
          { type: core.Component, args: [{selector: '[mat-menu-item]',
                      exportAs: 'matMenuItem',
                      inputs: ['disabled', 'disableRipple'],
                      host: {
                          'role': 'menuitem',
                          'class': 'mat-menu-item',
                          '[class.mat-menu-item-highlighted]': '_highlighted',
                          '[class.mat-menu-item-submenu-trigger]': '_triggersSubmenu',
                          '[attr.tabindex]': '_getTabIndex()',
                          '[attr.aria-disabled]': 'disabled.toString()',
                          '[attr.disabled]': 'disabled || null',
                          '(click)': '_checkDisabled($event)',
                          '(mouseenter)': '_handleMouseEnter()',
                      },
                      changeDetection: core.ChangeDetectionStrategy.OnPush,
                      encapsulation: core.ViewEncapsulation.None,
                      template: "<ng-content></ng-content><div class=\"mat-menu-ripple\" matRipple [matRippleDisabled]=\"disableRipple || disabled\" [matRippleTrigger]=\"_getHostElement()\"></div>",
                  },] },
      ];
      /** @nocollapse */
      MatMenuItem.ctorParameters = function () { return [
          { type: core.ElementRef, },
          { type: undefined, decorators: [{ type: core.Inject, args: [common.DOCUMENT,] },] },
          { type: a11y.FocusMonitor, },
          { type: undefined, decorators: [{ type: core.Inject, args: [MAT_MENU_PANEL,] }, { type: core.Optional },] },
      ]; };
      return MatMenuItem;
  }(_MatMenuItemMixinBase));
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * Injection token to be used to override the default options for `mat-menu`.
   */
  var /** @type {?} */ MAT_MENU_DEFAULT_OPTIONS = new core.InjectionToken('mat-menu-default-options', {
      providedIn: 'root',
      factory: MAT_MENU_DEFAULT_OPTIONS_FACTORY
  });
  /**
   * \@docs-private
   * @return {?}
   */
  function MAT_MENU_DEFAULT_OPTIONS_FACTORY() {
      return {
          overlapTrigger: true,
          xPosition: 'after',
          yPosition: 'below',
          backdropClass: 'cdk-overlay-transparent-backdrop',
      };
  }
  /**
   * Start elevation for the menu panel.
   * \@docs-private
   */
  var /** @type {?} */ MAT_MENU_BASE_ELEVATION = 2;
  var MatMenu = /** @class */ (function () {
      function MatMenu(_elementRef, _ngZone, _defaultOptions) {
          this._elementRef = _elementRef;
          this._ngZone = _ngZone;
          this._defaultOptions = _defaultOptions;
          this._xPosition = this._defaultOptions.xPosition;
          this._yPosition = this._defaultOptions.yPosition;
          /**
           * Menu items inside the current menu.
           */
          this._items = [];
          /**
           * Emits whenever the amount of menu items changes.
           */
          this._itemChanges = new rxjs.Subject();
          /**
           * Subscription to tab events on the menu panel
           */
          this._tabSubscription = rxjs.Subscription.EMPTY;
          /**
           * Config object to be passed into the menu's ngClass
           */
          this._classList = {};
          /**
           * Current state of the panel animation.
           */
          this._panelAnimationState = 'void';
          /**
           * Emits whenever an animation on the menu completes.
           */
          this._animationDone = new rxjs.Subject();
          /**
           * Class to be added to the backdrop element.
           */
          this.backdropClass = this._defaultOptions.backdropClass;
          this._overlapTrigger = this._defaultOptions.overlapTrigger;
          this._hasBackdrop = this._defaultOptions.hasBackdrop;
          /**
           * Event emitted when the menu is closed.
           */
          this.closed = new core.EventEmitter();
          /**
           * Event emitted when the menu is closed.
           * @deprecated Switch to `closed` instead
           * \@deletion-target 7.0.0
           */
          this.close = this.closed;
      }
      Object.defineProperty(MatMenu.prototype, "xPosition", {
          get: /**
           * Position of the menu in the X axis.
           * @return {?}
           */
          function () { return this._xPosition; },
          set: /**
           * @param {?} value
           * @return {?}
           */
          function (value) {
              if (value !== 'before' && value !== 'after') {
                  throwMatMenuInvalidPositionX();
              }
              this._xPosition = value;
              this.setPositionClasses();
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatMenu.prototype, "yPosition", {
          get: /**
           * Position of the menu in the Y axis.
           * @return {?}
           */
          function () { return this._yPosition; },
          set: /**
           * @param {?} value
           * @return {?}
           */
          function (value) {
              if (value !== 'above' && value !== 'below') {
                  throwMatMenuInvalidPositionY();
              }
              this._yPosition = value;
              this.setPositionClasses();
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatMenu.prototype, "overlapTrigger", {
          get: /**
           * Whether the menu should overlap its trigger.
           * @return {?}
           */
          function () { return this._overlapTrigger; },
          set: /**
           * @param {?} value
           * @return {?}
           */
          function (value) {
              this._overlapTrigger = coercion.coerceBooleanProperty(value);
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatMenu.prototype, "hasBackdrop", {
          get: /**
           * Whether the menu has a backdrop.
           * @return {?}
           */
          function () { return this._hasBackdrop; },
          set: /**
           * @param {?} value
           * @return {?}
           */
          function (value) {
              this._hasBackdrop = coercion.coerceBooleanProperty(value);
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatMenu.prototype, "panelClass", {
          set: /**
           * This method takes classes set on the host mat-menu element and applies them on the
           * menu template that displays in the overlay container.  Otherwise, it's difficult
           * to style the containing menu from outside the component.
           * @param {?} classes list of class names
           * @return {?}
           */
          function (classes) {
              if (classes && classes.length) {
                  this._classList = classes.split(' ').reduce(function (obj, className) {
                      obj[className] = true;
                      return obj;
                  }, {});
                  this._elementRef.nativeElement.className = '';
              }
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatMenu.prototype, "classList", {
          get: /**
           * This method takes classes set on the host mat-menu element and applies them on the
           * menu template that displays in the overlay container.  Otherwise, it's difficult
           * to style the containing menu from outside the component.
           * @deprecated Use `panelClass` instead.
           * \@deletion-target 7.0.0
           * @return {?}
           */
          function () { return this.panelClass; },
          set: /**
           * @param {?} classes
           * @return {?}
           */
          function (classes) { this.panelClass = classes; },
          enumerable: true,
          configurable: true
      });
      /**
       * @return {?}
       */
      MatMenu.prototype.ngOnInit = /**
       * @return {?}
       */
      function () {
          this.setPositionClasses();
      };
      /**
       * @return {?}
       */
      MatMenu.prototype.ngAfterContentInit = /**
       * @return {?}
       */
      function () {
          var _this = this;
          this._keyManager = new a11y.FocusKeyManager(this._items).withWrap().withTypeAhead();
          this._tabSubscription = this._keyManager.tabOut.subscribe(function () { return _this.closed.emit('tab'); });
      };
      /**
       * @return {?}
       */
      MatMenu.prototype.ngOnDestroy = /**
       * @return {?}
       */
      function () {
          this._tabSubscription.unsubscribe();
          this.closed.complete();
      };
      /** Stream that emits whenever the hovered menu item changes. */
      /**
       * Stream that emits whenever the hovered menu item changes.
       * @return {?}
       */
      MatMenu.prototype._hovered = /**
       * Stream that emits whenever the hovered menu item changes.
       * @return {?}
       */
      function () {
          return this._itemChanges.pipe(operators.startWith(this._items), operators.switchMap(function (items) { return rxjs.merge.apply(void 0, items.map(function (item) { return item._hovered; })); }));
      };
      /** Handle a keyboard event from the menu, delegating to the appropriate action. */
      /**
       * Handle a keyboard event from the menu, delegating to the appropriate action.
       * @param {?} event
       * @return {?}
       */
      MatMenu.prototype._handleKeydown = /**
       * Handle a keyboard event from the menu, delegating to the appropriate action.
       * @param {?} event
       * @return {?}
       */
      function (event) {
          var /** @type {?} */ keyCode = event.keyCode;
          switch (keyCode) {
              case keycodes.ESCAPE:
                  this.closed.emit('keydown');
                  event.stopPropagation();
                  break;
              case keycodes.LEFT_ARROW:
                  if (this.parentMenu && this.direction === 'ltr') {
                      this.closed.emit('keydown');
                  }
                  break;
              case keycodes.RIGHT_ARROW:
                  if (this.parentMenu && this.direction === 'rtl') {
                      this.closed.emit('keydown');
                  }
                  break;
              default:
                  if (keyCode === keycodes.UP_ARROW || keyCode === keycodes.DOWN_ARROW) {
                      this._keyManager.setFocusOrigin('keyboard');
                  }
                  this._keyManager.onKeydown(event);
          }
      };
      /**
       * Focus the first item in the menu.
       * @param origin Action from which the focus originated. Used to set the correct styling.
       */
      /**
       * Focus the first item in the menu.
       * @param {?=} origin Action from which the focus originated. Used to set the correct styling.
       * @return {?}
       */
      MatMenu.prototype.focusFirstItem = /**
       * Focus the first item in the menu.
       * @param {?=} origin Action from which the focus originated. Used to set the correct styling.
       * @return {?}
       */
      function (origin) {
          var _this = this;
          if (origin === void 0) { origin = 'program'; }
          // When the content is rendered lazily, it takes a bit before the items are inside the DOM.
          if (this.lazyContent) {
              this._ngZone.onStable.asObservable()
                  .pipe(operators.take(1))
                  .subscribe(function () { return _this._keyManager.setFocusOrigin(origin).setFirstItemActive(); });
          }
          else {
              this._keyManager.setFocusOrigin(origin).setFirstItemActive();
          }
      };
      /**
       * Resets the active item in the menu. This is used when the menu is opened, allowing
       * the user to start from the first option when pressing the down arrow.
       */
      /**
       * Resets the active item in the menu. This is used when the menu is opened, allowing
       * the user to start from the first option when pressing the down arrow.
       * @return {?}
       */
      MatMenu.prototype.resetActiveItem = /**
       * Resets the active item in the menu. This is used when the menu is opened, allowing
       * the user to start from the first option when pressing the down arrow.
       * @return {?}
       */
      function () {
          this._keyManager.setActiveItem(-1);
      };
      /**
       * Sets the menu panel elevation.
       * @param depth Number of parent menus that come before the menu.
       */
      /**
       * Sets the menu panel elevation.
       * @param {?} depth Number of parent menus that come before the menu.
       * @return {?}
       */
      MatMenu.prototype.setElevation = /**
       * Sets the menu panel elevation.
       * @param {?} depth Number of parent menus that come before the menu.
       * @return {?}
       */
      function (depth) {
          // The elevation starts at the base and increases by one for each level.
          var /** @type {?} */ newElevation = "mat-elevation-z" + (MAT_MENU_BASE_ELEVATION + depth);
          var /** @type {?} */ customElevation = Object.keys(this._classList).find(function (c) { return c.startsWith('mat-elevation-z'); });
          if (!customElevation || customElevation === this._previousElevation) {
              if (this._previousElevation) {
                  this._classList[this._previousElevation] = false;
              }
              this._classList[newElevation] = true;
              this._previousElevation = newElevation;
          }
      };
      /**
       * Registers a menu item with the menu.
       * @docs-private
       */
      /**
       * Registers a menu item with the menu.
       * \@docs-private
       * @param {?} item
       * @return {?}
       */
      MatMenu.prototype.addItem = /**
       * Registers a menu item with the menu.
       * \@docs-private
       * @param {?} item
       * @return {?}
       */
      function (item) {
          // We register the items through this method, rather than picking them up through
          // `ContentChildren`, because we need the items to be picked up by their closest
          // `mat-menu` ancestor. If we used `@ContentChildren(MatMenuItem, {descendants: true})`,
          // all descendant items will bleed into the top-level menu in the case where the consumer
          // has `mat-menu` instances nested inside each other.
          if (this._items.indexOf(item) === -1) {
              this._items.push(item);
              this._itemChanges.next(this._items);
          }
      };
      /**
       * Removes an item from the menu.
       * @docs-private
       */
      /**
       * Removes an item from the menu.
       * \@docs-private
       * @param {?} item
       * @return {?}
       */
      MatMenu.prototype.removeItem = /**
       * Removes an item from the menu.
       * \@docs-private
       * @param {?} item
       * @return {?}
       */
      function (item) {
          var /** @type {?} */ index = this._items.indexOf(item);
          if (this._items.indexOf(item) > -1) {
              this._items.splice(index, 1);
              this._itemChanges.next(this._items);
          }
      };
      /**
       * Adds classes to the menu panel based on its position. Can be used by
       * consumers to add specific styling based on the position.
       * @param posX Position of the menu along the x axis.
       * @param posY Position of the menu along the y axis.
       * @docs-private
       */
      /**
       * Adds classes to the menu panel based on its position. Can be used by
       * consumers to add specific styling based on the position.
       * \@docs-private
       * @param {?=} posX Position of the menu along the x axis.
       * @param {?=} posY Position of the menu along the y axis.
       * @return {?}
       */
      MatMenu.prototype.setPositionClasses = /**
       * Adds classes to the menu panel based on its position. Can be used by
       * consumers to add specific styling based on the position.
       * \@docs-private
       * @param {?=} posX Position of the menu along the x axis.
       * @param {?=} posY Position of the menu along the y axis.
       * @return {?}
       */
      function (posX, posY) {
          if (posX === void 0) { posX = this.xPosition; }
          if (posY === void 0) { posY = this.yPosition; }
          var /** @type {?} */ classes = this._classList;
          classes['mat-menu-before'] = posX === 'before';
          classes['mat-menu-after'] = posX === 'after';
          classes['mat-menu-above'] = posY === 'above';
          classes['mat-menu-below'] = posY === 'below';
      };
      /** Starts the enter animation. */
      /**
       * Starts the enter animation.
       * @return {?}
       */
      MatMenu.prototype._startAnimation = /**
       * Starts the enter animation.
       * @return {?}
       */
      function () {
          // @deletion-target 7.0.0 Combine with _resetAnimation.
          this._panelAnimationState = 'enter';
      };
      /** Resets the panel animation to its initial state. */
      /**
       * Resets the panel animation to its initial state.
       * @return {?}
       */
      MatMenu.prototype._resetAnimation = /**
       * Resets the panel animation to its initial state.
       * @return {?}
       */
      function () {
          // @deletion-target 7.0.0 Combine with _startAnimation.
          this._panelAnimationState = 'void';
      };
      /** Callback that is invoked when the panel animation completes. */
      /**
       * Callback that is invoked when the panel animation completes.
       * @param {?} event
       * @return {?}
       */
      MatMenu.prototype._onAnimationDone = /**
       * Callback that is invoked when the panel animation completes.
       * @param {?} event
       * @return {?}
       */
      function (event) {
          this._animationDone.next(event);
          this._isAnimating = false;
          // Scroll the content element to the top once the animation is done. This is necessary, because
          // we move focus to the first item while it's still being animated, which can throw the browser
          // off when it determines the scroll position. Alternatively we can move focus when the
          // animation is done, however moving focus asynchronously will interrupt screen readers
          // which are in the process of reading out the menu already. We take the `element` from
          // the `event` since we can't use a `ViewChild` to access the pane.
          if (event.toState === 'enter' && this._keyManager.activeItemIndex === 0) {
              event.element.scrollTop = 0;
          }
      };
      MatMenu.decorators = [
          { type: core.Component, args: [{selector: 'mat-menu',
                      template: "<ng-template><div class=\"mat-menu-panel\" [ngClass]=\"_classList\" (keydown)=\"_handleKeydown($event)\" (click)=\"closed.emit('click')\" [@transformMenu]=\"_panelAnimationState\" (@transformMenu.start)=\"_isAnimating = true\" (@transformMenu.done)=\"_onAnimationDone($event)\" tabindex=\"-1\" role=\"menu\"><div class=\"mat-menu-content\"><ng-content></ng-content></div></div></ng-template>",
                      styles: [".mat-menu-panel{min-width:112px;max-width:280px;overflow:auto;-webkit-overflow-scrolling:touch;max-height:calc(100vh - 48px);border-radius:2px;outline:0}.mat-menu-panel:not([class*=mat-elevation-z]){box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}@media screen and (-ms-high-contrast:active){.mat-menu-panel{outline:solid 1px}}.mat-menu-content{padding-top:8px;padding-bottom:8px}.mat-menu-item{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer;outline:0;border:none;-webkit-tap-highlight-color:transparent;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;line-height:48px;height:48px;padding:0 16px;text-align:left;text-decoration:none;position:relative}.mat-menu-item::-moz-focus-inner{border:0}.mat-menu-item[disabled]{cursor:default}[dir=rtl] .mat-menu-item{text-align:right}.mat-menu-item .mat-icon{margin-right:16px;vertical-align:middle}.mat-menu-item .mat-icon svg{vertical-align:top}[dir=rtl] .mat-menu-item .mat-icon{margin-left:16px;margin-right:0}.mat-menu-item-submenu-trigger{padding-right:32px}.mat-menu-item-submenu-trigger::after{width:0;height:0;border-style:solid;border-width:5px 0 5px 5px;border-color:transparent transparent transparent currentColor;content:'';display:inline-block;position:absolute;top:50%;right:16px;transform:translateY(-50%)}[dir=rtl] .mat-menu-item-submenu-trigger{padding-right:16px;padding-left:32px}[dir=rtl] .mat-menu-item-submenu-trigger::after{right:auto;left:16px;transform:rotateY(180deg) translateY(-50%)}.mat-menu-panel.ng-animating .mat-menu-item-submenu-trigger{pointer-events:none}button.mat-menu-item{width:100%}.mat-menu-ripple{top:0;left:0;right:0;bottom:0;position:absolute;pointer-events:none}"],
                      changeDetection: core.ChangeDetectionStrategy.OnPush,
                      encapsulation: core.ViewEncapsulation.None,
                      exportAs: 'matMenu',
                      animations: [
                          matMenuAnimations.transformMenu,
                          matMenuAnimations.fadeInItems
                      ],
                      providers: [
                          { provide: MAT_MENU_PANEL, useExisting: MatMenu }
                      ]
                  },] },
      ];
      /** @nocollapse */
      MatMenu.ctorParameters = function () { return [
          { type: core.ElementRef, },
          { type: core.NgZone, },
          { type: undefined, decorators: [{ type: core.Inject, args: [MAT_MENU_DEFAULT_OPTIONS,] },] },
      ]; };
      MatMenu.propDecorators = {
          "backdropClass": [{ type: core.Input },],
          "xPosition": [{ type: core.Input },],
          "yPosition": [{ type: core.Input },],
          "templateRef": [{ type: core.ViewChild, args: [core.TemplateRef,] },],
          "items": [{ type: core.ContentChildren, args: [MatMenuItem,] },],
          "lazyContent": [{ type: core.ContentChild, args: [MatMenuContent,] },],
          "overlapTrigger": [{ type: core.Input },],
          "hasBackdrop": [{ type: core.Input },],
          "panelClass": [{ type: core.Input, args: ['class',] },],
          "classList": [{ type: core.Input },],
          "closed": [{ type: core.Output },],
          "close": [{ type: core.Output },],
      };
      return MatMenu;
  }());
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  /**
   * Injection token that determines the scroll handling while the menu is open.
   */
  var /** @type {?} */ MAT_MENU_SCROLL_STRATEGY = new core.InjectionToken('mat-menu-scroll-strategy');
  /**
   * \@docs-private
   * @param {?} overlay
   * @return {?}
   */
  function MAT_MENU_SCROLL_STRATEGY_FACTORY(overlay$$1) {
      return function () { return overlay$$1.scrollStrategies.reposition(); };
  }
  /**
   * \@docs-private
   */
  var /** @type {?} */ MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER = {
      provide: MAT_MENU_SCROLL_STRATEGY,
      deps: [overlay.Overlay],
      useFactory: MAT_MENU_SCROLL_STRATEGY_FACTORY,
  };
  /**
   * Default top padding of the menu panel.
   */
  var /** @type {?} */ MENU_PANEL_TOP_PADDING = 8;
  /**
   * This directive is intended to be used in conjunction with an mat-menu tag.  It is
   * responsible for toggling the display of the provided menu instance.
   */
  var MatMenuTrigger = /** @class */ (function () {
      function MatMenuTrigger(_overlay, _element, _viewContainerRef, _scrollStrategy, _parentMenu, _menuItemInstance, _dir, _focusMonitor) {
          this._overlay = _overlay;
          this._element = _element;
          this._viewContainerRef = _viewContainerRef;
          this._scrollStrategy = _scrollStrategy;
          this._parentMenu = _parentMenu;
          this._menuItemInstance = _menuItemInstance;
          this._dir = _dir;
          this._focusMonitor = _focusMonitor;
          this._overlayRef = null;
          this._menuOpen = false;
          this._closeSubscription = rxjs.Subscription.EMPTY;
          this._hoverSubscription = rxjs.Subscription.EMPTY;
          this._openedByMouse = false;
          /**
           * Event emitted when the associated menu is opened.
           */
          this.menuOpened = new core.EventEmitter();
          /**
           * Event emitted when the associated menu is opened.
           * @deprecated Switch to `menuOpened` instead
           * \@deletion-target 7.0.0
           */
          this.onMenuOpen = this.menuOpened;
          /**
           * Event emitted when the associated menu is closed.
           */
          this.menuClosed = new core.EventEmitter();
          /**
           * Event emitted when the associated menu is closed.
           * @deprecated Switch to `menuClosed` instead
           * \@deletion-target 7.0.0
           */
          this.onMenuClose = this.menuClosed;
          if (_menuItemInstance) {
              _menuItemInstance._triggersSubmenu = this.triggersSubmenu();
          }
      }
      Object.defineProperty(MatMenuTrigger.prototype, "_deprecatedMatMenuTriggerFor", {
          get: /**
           * @deprecated
           * \@deletion-target 7.0.0
           * @return {?}
           */
          function () {
              return this.menu;
          },
          set: /**
           * @param {?} v
           * @return {?}
           */
          function (v) {
              this.menu = v;
          },
          enumerable: true,
          configurable: true
      });
      /**
       * @return {?}
       */
      MatMenuTrigger.prototype.ngAfterContentInit = /**
       * @return {?}
       */
      function () {
          var _this = this;
          this._checkMenu();
          this.menu.close.subscribe(function (reason) {
              _this._destroyMenu();
              // If a click closed the menu, we should close the entire chain of nested menus.
              if ((reason === 'click' || reason === 'tab') && _this._parentMenu) {
                  _this._parentMenu.closed.emit(reason);
              }
          });
          this._handleHover();
      };
      /**
       * @return {?}
       */
      MatMenuTrigger.prototype.ngOnDestroy = /**
       * @return {?}
       */
      function () {
          if (this._overlayRef) {
              this._overlayRef.dispose();
              this._overlayRef = null;
          }
          this._cleanUpSubscriptions();
      };
      Object.defineProperty(MatMenuTrigger.prototype, "menuOpen", {
          /** Whether the menu is open. */
          get: /**
           * Whether the menu is open.
           * @return {?}
           */
          function () {
              return this._menuOpen;
          },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(MatMenuTrigger.prototype, "dir", {
          /** The text direction of the containing app. */
          get: /**
           * The text direction of the containing app.
           * @return {?}
           */
          function () {
              return this._dir && this._dir.value === 'rtl' ? 'rtl' : 'ltr';
          },
          enumerable: true,
          configurable: true
      });
      /** Whether the menu triggers a sub-menu or a top-level one. */
      /**
       * Whether the menu triggers a sub-menu or a top-level one.
       * @return {?}
       */
      MatMenuTrigger.prototype.triggersSubmenu = /**
       * Whether the menu triggers a sub-menu or a top-level one.
       * @return {?}
       */
      function () {
          return !!(this._menuItemInstance && this._parentMenu);
      };
      /** Toggles the menu between the open and closed states. */
      /**
       * Toggles the menu between the open and closed states.
       * @return {?}
       */
      MatMenuTrigger.prototype.toggleMenu = /**
       * Toggles the menu between the open and closed states.
       * @return {?}
       */
      function () {
          return this._menuOpen ? this.closeMenu() : this.openMenu();
      };
      /** Opens the menu. */
      /**
       * Opens the menu.
       * @return {?}
       */
      MatMenuTrigger.prototype.openMenu = /**
       * Opens the menu.
       * @return {?}
       */
      function () {
          var _this = this;
          if (this._menuOpen) {
              return;
          }
          var /** @type {?} */ overlayRef = this._createOverlay();
          this._setPosition(/** @type {?} */ (overlayRef.getConfig().positionStrategy));
          overlayRef.attach(this._portal);
          if (this.menu.lazyContent) {
              this.menu.lazyContent.attach(this.menuData);
          }
          this._closeSubscription = this._menuClosingActions().subscribe(function () { return _this.closeMenu(); });
          this._initMenu();
          if (this.menu instanceof MatMenu) {
              this.menu._startAnimation();
          }
      };
      /** Closes the menu. */
      /**
       * Closes the menu.
       * @return {?}
       */
      MatMenuTrigger.prototype.closeMenu = /**
       * Closes the menu.
       * @return {?}
       */
      function () {
          this.menu.close.emit();
      };
      /**
       * Focuses the menu trigger.
       * @param origin Source of the menu trigger's focus.
       */
      /**
       * Focuses the menu trigger.
       * @param {?=} origin Source of the menu trigger's focus.
       * @return {?}
       */
      MatMenuTrigger.prototype.focus = /**
       * Focuses the menu trigger.
       * @param {?=} origin Source of the menu trigger's focus.
       * @return {?}
       */
      function (origin) {
          if (origin === void 0) { origin = 'program'; }
          if (this._focusMonitor) {
              this._focusMonitor.focusVia(this._element.nativeElement, origin);
          }
          else {
              this._element.nativeElement.focus();
          }
      };
      /**
       * Closes the menu and does the necessary cleanup.
       * @return {?}
       */
      MatMenuTrigger.prototype._destroyMenu = /**
       * Closes the menu and does the necessary cleanup.
       * @return {?}
       */
      function () {
          var _this = this;
          if (!this._overlayRef || !this.menuOpen) {
              return;
          }
          var /** @type {?} */ menu = this.menu;
          this._closeSubscription.unsubscribe();
          this._overlayRef.detach();
          if (menu instanceof MatMenu) {
              menu._resetAnimation();
              if (menu.lazyContent) {
                  // Wait for the exit animation to finish before detaching the content.
                  menu._animationDone
                      .pipe(operators.filter(function (event) { return event.toState === 'void'; }), operators.take(1))
                      .subscribe(function () {
                      /** @type {?} */ ((menu.lazyContent)).detach();
                      _this._resetMenu();
                  });
              }
              else {
                  this._resetMenu();
              }
          }
          else {
              this._resetMenu();
              if (menu.lazyContent) {
                  menu.lazyContent.detach();
              }
          }
      };
      /**
       * This method sets the menu state to open and focuses the first item if
       * the menu was opened via the keyboard.
       * @return {?}
       */
      MatMenuTrigger.prototype._initMenu = /**
       * This method sets the menu state to open and focuses the first item if
       * the menu was opened via the keyboard.
       * @return {?}
       */
      function () {
          this.menu.parentMenu = this.triggersSubmenu() ? this._parentMenu : undefined;
          this.menu.direction = this.dir;
          this._setMenuElevation();
          this._setIsMenuOpen(true);
          this.menu.focusFirstItem(this._openedByMouse ? 'mouse' : 'program');
      };
      /**
       * Updates the menu elevation based on the amount of parent menus that it has.
       * @return {?}
       */
      MatMenuTrigger.prototype._setMenuElevation = /**
       * Updates the menu elevation based on the amount of parent menus that it has.
       * @return {?}
       */
      function () {
          if (this.menu.setElevation) {
              var /** @type {?} */ depth = 0;
              var /** @type {?} */ parentMenu = this.menu.parentMenu;
              while (parentMenu) {
                  depth++;
                  parentMenu = parentMenu.parentMenu;
              }
              this.menu.setElevation(depth);
          }
      };
      /**
       * This method resets the menu when it's closed, most importantly restoring
       * focus to the menu trigger if the menu was opened via the keyboard.
       * @return {?}
       */
      MatMenuTrigger.prototype._resetMenu = /**
       * This method resets the menu when it's closed, most importantly restoring
       * focus to the menu trigger if the menu was opened via the keyboard.
       * @return {?}
       */
      function () {
          this._setIsMenuOpen(false);
          // We should reset focus if the user is navigating using a keyboard or
          // if we have a top-level trigger which might cause focus to be lost
          // when clicking on the backdrop.
          if (!this._openedByMouse) {
              // Note that the focus style will show up both for `program` and
              // `keyboard` so we don't have to specify which one it is.
              this.focus();
          }
          else if (!this.triggersSubmenu()) {
              this.focus('mouse');
          }
          this._openedByMouse = false;
      };
      /**
       * @param {?} isOpen
       * @return {?}
       */
      MatMenuTrigger.prototype._setIsMenuOpen = /**
       * @param {?} isOpen
       * @return {?}
       */
      function (isOpen) {
          this._menuOpen = isOpen;
          this._menuOpen ? this.menuOpened.emit() : this.menuClosed.emit();
          if (this.triggersSubmenu()) {
              this._menuItemInstance._highlighted = isOpen;
          }
      };
      /**
       * This method checks that a valid instance of MatMenu has been passed into
       * matMenuTriggerFor. If not, an exception is thrown.
       * @return {?}
       */
      MatMenuTrigger.prototype._checkMenu = /**
       * This method checks that a valid instance of MatMenu has been passed into
       * matMenuTriggerFor. If not, an exception is thrown.
       * @return {?}
       */
      function () {
          if (!this.menu) {
              throwMatMenuMissingError();
          }
      };
      /**
       * This method creates the overlay from the provided menu's template and saves its
       * OverlayRef so that it can be attached to the DOM when openMenu is called.
       * @return {?}
       */
      MatMenuTrigger.prototype._createOverlay = /**
       * This method creates the overlay from the provided menu's template and saves its
       * OverlayRef so that it can be attached to the DOM when openMenu is called.
       * @return {?}
       */
      function () {
          if (!this._overlayRef) {
              this._portal = new portal.TemplatePortal(this.menu.templateRef, this._viewContainerRef);
              var /** @type {?} */ config = this._getOverlayConfig();
              this._subscribeToPositions(/** @type {?} */ (config.positionStrategy));
              this._overlayRef = this._overlay.create(config);
          }
          return this._overlayRef;
      };
      /**
       * This method builds the configuration object needed to create the overlay, the OverlayState.
       * @return {?} OverlayConfig
       */
      MatMenuTrigger.prototype._getOverlayConfig = /**
       * This method builds the configuration object needed to create the overlay, the OverlayState.
       * @return {?} OverlayConfig
       */
      function () {
          return new overlay.OverlayConfig({
              positionStrategy: this._overlay.position()
                  .flexibleConnectedTo(this._element)
                  .withTransformOriginOn('.mat-menu-panel'),
              hasBackdrop: this.menu.hasBackdrop == null ? !this.triggersSubmenu() : this.menu.hasBackdrop,
              backdropClass: this.menu.backdropClass || 'cdk-overlay-transparent-backdrop',
              scrollStrategy: this._scrollStrategy(),
              direction: this._dir
          });
      };
      /**
       * Listens to changes in the position of the overlay and sets the correct classes
       * on the menu based on the new position. This ensures the animation origin is always
       * correct, even if a fallback position is used for the overlay.
       * @param {?} position
       * @return {?}
       */
      MatMenuTrigger.prototype._subscribeToPositions = /**
       * Listens to changes in the position of the overlay and sets the correct classes
       * on the menu based on the new position. This ensures the animation origin is always
       * correct, even if a fallback position is used for the overlay.
       * @param {?} position
       * @return {?}
       */
      function (position) {
          var _this = this;
          if (this.menu.setPositionClasses) {
              position.positionChanges.subscribe(function (change) {
                  var /** @type {?} */ posX = change.connectionPair.overlayX === 'start' ? 'after' : 'before';
                  var /** @type {?} */ posY = change.connectionPair.overlayY === 'top' ? 'below' : 'above'; /** @type {?} */
                  ((_this.menu.setPositionClasses))(posX, posY);
              });
          }
      };
      /**
       * Sets the appropriate positions on a position strategy
       * so the overlay connects with the trigger correctly.
       * @param {?} positionStrategy Strategy whose position to update.
       * @return {?}
       */
      MatMenuTrigger.prototype._setPosition = /**
       * Sets the appropriate positions on a position strategy
       * so the overlay connects with the trigger correctly.
       * @param {?} positionStrategy Strategy whose position to update.
       * @return {?}
       */
      function (positionStrategy) {
          var _a = this.menu.xPosition === 'before' ? ['end', 'start'] : ['start', 'end'], originX = _a[0], originFallbackX = _a[1];
          var _b = this.menu.yPosition === 'above' ? ['bottom', 'top'] : ['top', 'bottom'], overlayY = _b[0], overlayFallbackY = _b[1];
          var _c = [overlayY, overlayFallbackY], originY = _c[0], originFallbackY = _c[1];
          var _d = [originX, originFallbackX], overlayX = _d[0], overlayFallbackX = _d[1];
          var /** @type {?} */ offsetY = 0;
          if (this.triggersSubmenu()) {
              // When the menu is a sub-menu, it should always align itself
              // to the edges of the trigger, instead of overlapping it.
              overlayFallbackX = originX = this.menu.xPosition === 'before' ? 'start' : 'end';
              originFallbackX = overlayX = originX === 'end' ? 'start' : 'end';
              offsetY = overlayY === 'bottom' ? MENU_PANEL_TOP_PADDING : -MENU_PANEL_TOP_PADDING;
          }
          else if (!this.menu.overlapTrigger) {
              originY = overlayY === 'top' ? 'bottom' : 'top';
              originFallbackY = overlayFallbackY === 'top' ? 'bottom' : 'top';
          }
          positionStrategy.withPositions([
              { originX: originX, originY: originY, overlayX: overlayX, overlayY: overlayY, offsetY: offsetY },
              { originX: originFallbackX, originY: originY, overlayX: overlayFallbackX, overlayY: overlayY, offsetY: offsetY },
              {
                  originX: originX,
                  originY: originFallbackY,
                  overlayX: overlayX,
                  overlayY: overlayFallbackY,
                  offsetY: -offsetY
              },
              {
                  originX: originFallbackX,
                  originY: originFallbackY,
                  overlayX: overlayFallbackX,
                  overlayY: overlayFallbackY,
                  offsetY: -offsetY
              }
          ]);
      };
      /**
       * Cleans up the active subscriptions.
       * @return {?}
       */
      MatMenuTrigger.prototype._cleanUpSubscriptions = /**
       * Cleans up the active subscriptions.
       * @return {?}
       */
      function () {
          this._closeSubscription.unsubscribe();
          this._hoverSubscription.unsubscribe();
      };
      /**
       * Returns a stream that emits whenever an action that should close the menu occurs.
       * @return {?}
       */
      MatMenuTrigger.prototype._menuClosingActions = /**
       * Returns a stream that emits whenever an action that should close the menu occurs.
       * @return {?}
       */
      function () {
          var _this = this;
          var /** @type {?} */ backdrop = /** @type {?} */ ((this._overlayRef)).backdropClick();
          var /** @type {?} */ detachments = /** @type {?} */ ((this._overlayRef)).detachments();
          var /** @type {?} */ parentClose = this._parentMenu ? this._parentMenu.closed : rxjs.of();
          var /** @type {?} */ hover = this._parentMenu ? this._parentMenu._hovered().pipe(operators.filter(function (active) { return active !== _this._menuItemInstance; }), operators.filter(function () { return _this._menuOpen; })) : rxjs.of();
          return rxjs.merge(backdrop, parentClose, hover, detachments);
      };
      /** Handles mouse presses on the trigger. */
      /**
       * Handles mouse presses on the trigger.
       * @param {?} event
       * @return {?}
       */
      MatMenuTrigger.prototype._handleMousedown = /**
       * Handles mouse presses on the trigger.
       * @param {?} event
       * @return {?}
       */
      function (event) {
          if (!a11y.isFakeMousedownFromScreenReader(event)) {
              this._openedByMouse = true;
              // Since clicking on the trigger won't close the menu if it opens a sub-menu,
              // we should prevent focus from moving onto it via click to avoid the
              // highlight from lingering on the menu item.
              if (this.triggersSubmenu()) {
                  event.preventDefault();
              }
          }
      };
      /** Handles key presses on the trigger. */
      /**
       * Handles key presses on the trigger.
       * @param {?} event
       * @return {?}
       */
      MatMenuTrigger.prototype._handleKeydown = /**
       * Handles key presses on the trigger.
       * @param {?} event
       * @return {?}
       */
      function (event) {
          var /** @type {?} */ keyCode = event.keyCode;
          if (this.triggersSubmenu() && ((keyCode === keycodes.RIGHT_ARROW && this.dir === 'ltr') ||
              (keyCode === keycodes.LEFT_ARROW && this.dir === 'rtl'))) {
              this.openMenu();
          }
      };
      /** Handles click events on the trigger. */
      /**
       * Handles click events on the trigger.
       * @param {?} event
       * @return {?}
       */
      MatMenuTrigger.prototype._handleClick = /**
       * Handles click events on the trigger.
       * @param {?} event
       * @return {?}
       */
      function (event) {
          if (this.triggersSubmenu()) {
              // Stop event propagation to avoid closing the parent menu.
              event.stopPropagation();
              this.openMenu();
          }
          else {
              this.toggleMenu();
          }
      };
      /**
       * Handles the cases where the user hovers over the trigger.
       * @return {?}
       */
      MatMenuTrigger.prototype._handleHover = /**
       * Handles the cases where the user hovers over the trigger.
       * @return {?}
       */
      function () {
          var _this = this;
          // Subscribe to changes in the hovered item in order to toggle the panel.
          if (!this.triggersSubmenu()) {
              return;
          }
          this._hoverSubscription = this._parentMenu._hovered()
              .pipe(operators.filter(function (active) { return active === _this._menuItemInstance && !active.disabled; }), operators.delay(0, rxjs.asapScheduler))
              .subscribe(function () {
              _this._openedByMouse = true;
              // If the same menu is used between multiple triggers, it might still be animating
              // while the new trigger tries to re-open it. Wait for the animation to finish
              // before doing so. Also interrupt if the user moves to another item.
              if (_this.menu instanceof MatMenu && _this.menu._isAnimating) {
                  _this.menu._animationDone
                      .pipe(operators.take(1), operators.takeUntil(_this._parentMenu._hovered()))
                      .subscribe(function () { return _this.openMenu(); });
              }
              else {
                  _this.openMenu();
              }
          });
      };
      MatMenuTrigger.decorators = [
          { type: core.Directive, args: [{
                      selector: "[mat-menu-trigger-for], [matMenuTriggerFor]",
                      host: {
                          'aria-haspopup': 'true',
                          '[attr.aria-expanded]': 'menuOpen || null',
                          '(mousedown)': '_handleMousedown($event)',
                          '(keydown)': '_handleKeydown($event)',
                          '(click)': '_handleClick($event)',
                      },
                      exportAs: 'matMenuTrigger'
                  },] },
      ];
      /** @nocollapse */
      MatMenuTrigger.ctorParameters = function () { return [
          { type: overlay.Overlay, },
          { type: core.ElementRef, },
          { type: core.ViewContainerRef, },
          { type: undefined, decorators: [{ type: core.Inject, args: [MAT_MENU_SCROLL_STRATEGY,] },] },
          { type: MatMenu, decorators: [{ type: core.Optional },] },
          { type: MatMenuItem, decorators: [{ type: core.Optional }, { type: core.Self },] },
          { type: bidi.Directionality, decorators: [{ type: core.Optional },] },
          { type: a11y.FocusMonitor, },
      ]; };
      MatMenuTrigger.propDecorators = {
          "_deprecatedMatMenuTriggerFor": [{ type: core.Input, args: ['mat-menu-trigger-for',] },],
          "menu": [{ type: core.Input, args: ['matMenuTriggerFor',] },],
          "menuData": [{ type: core.Input, args: ['matMenuTriggerData',] },],
          "menuOpened": [{ type: core.Output },],
          "onMenuOpen": [{ type: core.Output },],
          "menuClosed": [{ type: core.Output },],
          "onMenuClose": [{ type: core.Output },],
      };
      return MatMenuTrigger;
  }());
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes} checked by tsc
   */
  var MatMenuModule = /** @class */ (function () {
      function MatMenuModule() {
      }
      MatMenuModule.decorators = [
          { type: core.NgModule, args: [{
                      imports: [
                          common.CommonModule,
                          core$1.MatCommonModule,
                          core$1.MatRippleModule,
                          overlay.OverlayModule,
                      ],
                      exports: [MatMenu, MatMenuItem, MatMenuTrigger, MatMenuContent, core$1.MatCommonModule],
                      declarations: [MatMenu, MatMenuItem, MatMenuTrigger, MatMenuContent],
                      providers: [MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER]
                  },] },
      ];
      return MatMenuModule;
  }());
  
  exports.MAT_MENU_SCROLL_STRATEGY = MAT_MENU_SCROLL_STRATEGY;
  exports.MatMenuModule = MatMenuModule;
  exports.MatMenu = MatMenu;
  exports.MAT_MENU_DEFAULT_OPTIONS = MAT_MENU_DEFAULT_OPTIONS;
  exports.MatMenuItem = MatMenuItem;
  exports.MatMenuTrigger = MatMenuTrigger;
  exports.matMenuAnimations = matMenuAnimations;
  exports.fadeInItems = fadeInItems;
  exports.transformMenu = transformMenu;
  exports.MatMenuContent = MatMenuContent;
  exports.ɵa24 = MAT_MENU_DEFAULT_OPTIONS_FACTORY;
  exports.ɵb24 = MatMenuItemBase;
  exports.ɵc24 = _MatMenuItemMixinBase;
  exports.ɵf24 = MAT_MENU_PANEL;
  exports.ɵd24 = MAT_MENU_SCROLL_STRATEGY_FACTORY;
  exports.ɵe24 = MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER;
  
  Object.defineProperty(exports, '__esModule', { value: true });
  
  })));
  //# sourceMappingURL=material-menu.umd.js.map
  